Exemple #1
0
    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);
Exemple #2
0
    def isKstLL(b0meson, togenmatchleptons, togenmatchhadrons, flav=13):
        #         isB0 = (b0meson.pdgId()==511)
        #         isAntiB0 = (not isB0)
        # positive-charged leptons
        lps = [ip for ip in b0meson.finaldaughters if ip.pdgId() == -abs(flav)]
        # negative-charged leptons
        lms = [ip for ip in b0meson.finaldaughters if ip.pdgId() == abs(flav)]
        # pions from K*
        pis = [ip for ip in b0meson.finaldaughters if abs(ip.pdgId()) == 211]
        # kaons from K*
        ks = [ip for ip in b0meson.finaldaughters if abs(ip.pdgId()) == 321]

        for ilep in lps + lms:
            # avoid matching the same particle twice, use the charge to distinguish (charge flip not accounted...)
            tomatch = [
                jj for jj in togenmatchleptons if jj.charge() == ilep.charge()
            ]
            bm, dr = bestMatch(ilep, tomatch)
            if dr < 0.3:
                ilep.reco = bm

        for ihad in pis + ks:
            # avoid matching the same particle twice, use the charge to distinguish (charge flip not accounted...)
            tomatch = [
                jj for jj in togenmatchhadrons if jj.charge() == ihad.charge()
            ]
            bm, dr = bestMatch(ihad, tomatch)
            if dr < 0.3:
                ihad.reco = bm

        if len(lps) == len(lms) == len(pis) == len(ks) == 1:
            return True, lps[0], lms[0], pis[0], ks[0]
        else:
            return False, None, None, None, None
Exemple #3
0
    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);
Exemple #4
0
    def process(self, event):
        if event.input.eventAuxiliary().isRealData():
            return True

        # match the refitted tau to gen tau
        tau = event.tau3muRefit.p4Muons()
        best_match, dRmin = bestMatch(tau, event.gentaus)
        tau_match = best_match if dRmin < 0.3 else None

        muons = [
            event.tau3muRefit.mu1(),
            event.tau3muRefit.mu2(),
            event.tau3muRefit.mu3()
        ]

        # now match the three muons:
        #    first try to match to any stable gen particle
        stableGenParticles = [
            pp for pp in event.genParticles if pp.status() == 2
        ]
        for mu in muons:
            best_match, dRmin = bestMatch(mu, stableGenParticles)
            if dRmin < 0.1:
                mu.genp = best_match

        #     then match to tau daughters
        #     but only if the reco tau is matched to a gen tau itself
        if tau_match:
            # append the gen tau to the event
            event.gentau = tau_match
            tau_daughters = list(tau_match.daughterRefVector())
            for mu in muons:
                best_match, dRmin = bestMatch(mu, tau_daughters)
                if dRmin < 0.1:
                    mu.genp = best_match
            # check if the tau comes from a w
            tau_genw = [
                pp for pp in list(tau_match.motherRefVector())
                if abs(pp.pdgId()) == 24
            ]
            if tau_genw:
                event.genw = tau_genw[0]

        neutrinos = [
            pp for pp in event.genParticles if abs(pp.pdgId()) in [12, 14, 16]
        ]

        for i, nn in enumerate(neutrinos):
            if i == 0:
                event.genmet = nn.p4()
            else:
                event.genmet += nn.p4()

#         import pdb ; pdb.set_trace()

        return True
    def process(self, event):
        self.readCollections(event.input)

        event.taus = [Tau(tau) for tau in self.handles['taus'].product()]
        event.gen = self.handles['gen'].product()
        event.genParticles = event.gen
        event.genJets = self.handles['gen_jets'].product()

        for pu_info in self.handles['pu'].product():
            if pu_info.getBunchCrossing() == 0:
                event.n_true_interactions = pu_info.getTrueNumInteractions()

        event.genleps = [p for p in event.gen if abs(p.pdgId()) in [11, 13] and p.statusFlags().isPrompt()]
        event.gentauleps = [p for p in event.gen if abs(p.pdgId()) in [11, 13] and p.statusFlags().isDirectPromptTauDecayProduct()]
        event.gentaus = [p for p in event.gen if abs(p.pdgId()) == 15 and p.statusFlags().isPrompt() and not any(abs(HTTGenAnalyzer.getFinalTau(p).daughter(i_d).pdgId()) in [11, 13] for i_d in xrange(HTTGenAnalyzer.getFinalTau(p).numberOfDaughters()))]

        HTTGenAnalyzer.getGenTauJets(event) # saves event.genTauJets

        for gen_tau in event.genTauJets:
            gen_tau.charged = [d for d in gen_tau.daughters if d.charge()]
            gen_tau.pizeros = [daughters(d) for d in gen_tau.daughters if d.pdgId() == 111]

        pf_candidates = self.handles['pf_candidates'].product()

        for tau in event.taus:
            TauIsoAnalyzer.addInfo(tau, event, [c for c in pf_candidates if abs(c.pdgId()) == 211], maxDeltaR=0.8)
            matched_gen_jet, dr2 = bestMatch(tau, event.genJets)
            if dr2 < 0.25:
                tau.gen_jet = matched_gen_jet

        return True
Exemple #6
0
def XZZmatchObjectCollection(objects,
                             matchCollection,
                             deltaR2Max,
                             dPtMaxFactor,
                             filter=lambda x, y: True):
    ''' @ Apr-6-16 Adds genJets matching for JER according to 
    https://github.com/cms-sw/cmssw/blob/518995a62433825453d7ccf9ec222d782086cad9/PhysicsTools/PatUtils/interface/SmearedJetProducerT.h
    
    used to produce the sync table:
    https://twiki.cern.ch/twiki/bin/view/CMS/JERCReference
    '''
    pairs = {}
    if len(objects) == 0:
        return pairs
    if len(matchCollection) == 0:
        return dict(zip(objects, [None] * len(objects)))
    for object in objects:
        bm, dr2 = bestMatch(
            object, [mob for mob in matchCollection if filter(object, mob)])
        dPt = abs(bm.pt() - object.pt())
        if dr2 < deltaR2Max and dPt < dPtMaxFactor * object.pt(
        ) * object.resolution:
            pairs[object] = bm
        else:
            pairs[object] = None
    return pairs
Exemple #7
0
    def genMatch(self, event, dR=0.3):

        dR2 = dR * dR

        # match the tau_h leg
        # to generated had taus
        l1match, dR2best = bestMatch(self.l1, event.gentaus)
        if dR2best < dR2:
            self.l1.genp = l1match
            self.l1.isTauHad = True

        # to generated leptons from taus
        if not self.l1.isTauHad:
            l1match, dR2best = bestMatch(self.l1, self.ptSelGentauleps)
            if dR2best < dR2:
                self.l1.genp = l1match
                self.l1.isTauLep = True

        # to generated prompt leptons
        elif not self.l1.isTauLep:
            l1match, dR2best = bestMatch(self.l1, self.ptSelGenleps)
            if dR2best < dR2:
                self.l1.genp = l1match
                self.l1.isPromptLep = True

        # match with any other gen particle
        elif not self.l1.isPromptLep:
            l1match, dR2best = bestMatch(self.l1, event.genParticles)
            if dR2best < dR2:
                self.l1.genp = l1match

        # match the mu leg
        # to generated had taus
        l2match, dR2best = bestMatch(self.l2, event.gentaus)
        if dR2best < dR2:
            self.l2.genp = l2match
            self.l2.isTauHad = True

        # to generated leptons from taus
        if not self.l2.isTauHad:
            l2match, dR2best = bestMatch(self.l2, self.ptSelGentauleps)
            if dR2best < dR2:
                self.l2.genp = l2match
                self.l2.isTauLep = True

        # to generated prompt leptons
        elif not self.l2.isTauLep:
            l2match, dR2best = bestMatch(self.l2, self.ptSelGenleps)
            if dR2best < dR2:
                self.l2.genp = l2match
                self.l2.isPromptLep = True

        # match with any other gen particle
        elif not self.l2.isPromptLep:
            l2match, dR2best = bestMatch(self.l2, event.genParticles)
            if dR2best < dR2:
                self.l2.genp = l2match
 def attachJets(self, quad, jets):
     # must clean jets from the leptons in the candidate in addition to the ones already cleaned
     leptonsAndPhotons = quad.daughterLeptons() + quad.daughterPhotons()
     quad.cleanJets = []
     quad.cleanJetIndices = []
     for ij, j in enumerate(jets):
         bm, dr2 = bestMatch(j, leptonsAndPhotons)
         if dr2 < 0.4**2:
             continue
         quad.cleanJets.append(j)
         quad.cleanJetIndices.append(ij)
Exemple #9
0
 def matchL1TriggerObject(self, to):
     l1to, dR2 = bestMatch(to, self.l1tos)
     if hasattr(self.cfg_comp, 'channel') and self.cfg_comp.channel == 'tt':
         ptcut = 31.9999
     else:
         ptcut = 0
     if dR2 < 0.25 and l1to.Pt() > ptcut:
         return True
     # for l1to in self.l1tos:
     #     if deltaR2(to.eta(),to.phi(),l1to.Eta(),l1to.Phi()) < 0.25 and l1to.Pt()>31.9999:# because some come with 31.999999999996 and are passed by KIT
     #         return True
     return False
Exemple #10
0
def single_muon(muons, pt, eta=2.5, qual=8, matches=[], cone=0.3, onlymuons=False, atvtx=True):
    
    cone2 = cone * cone
    
    results = []
    
    for mu in muons:
        matched = False
        dRmin = 999.
        if mu.hwQual()   < qual: continue
        if mu.pt()       < pt  : continue
        if abs(mu.eta()) > eta : continue
        
        mu_for_matching = mu.clone()
        if atvtx:
            mu_for_matching.eta = mu.etaAtVtx
            mu_for_matching.phi = mu.phiAtVtx
        
        match_index = -99
                
        for ii, imatch in enumerate(matches):
            imatch.matched = False
            matched = False
            if onlymuons:
                best_match, dRmin = bestMatch(mu_for_matching, imatch.finalmuondaughters)            
            else:
                best_match, dRmin = bestMatch(mu_for_matching, imatch.finalchargeddaughters)
            matched = dRmin<cone2
            if matched: 
                match_index = ii
                imatch.matched = True
                break
        
        results.append((1, int(matched), match_index))
    
    if len(results)>0:
        results.sort(key = lambda x : (x[0], x[1]), reverse=True)
        return int(results[0][0]), int(results[0][1]), int(results[0][2])

    return 0, 0, -1
Exemple #11
0
    def makeVetoLeptons(self, event):
        ### selected leptons = subset of inclusive leptons passing some basic id definition and pt requirement
        ### other    leptons = subset of inclusive leptons failing some basic id definition and pt requirement
        event.vetoLeptons = []
        event.vetoMuons = []
        event.vetoElectrons = []

        #the selected leptons are the ones with the corrections / calibrations applied
        # make veto leptons
        for mu in event.selectedMuons:
            if (mu.pt() > self.cfg_ana.veto_muon_pt
                    and abs(mu.eta()) < self.cfg_ana.veto_muon_eta
                    and abs(mu.dxy()) < self.cfg_ana.veto_muon_dxy
                    and abs(mu.dz()) < self.cfg_ana.veto_muon_dz
                    and self.muIsoCut(mu)):
                mu.vetoIdMonoX = True
                event.vetoLeptons.append(mu)
                event.vetoMuons.append(mu)
            else:
                mu.vetoIdMonoX = False
        vetoMuons = event.vetoLeptons[:]
        for ele in event.selectedElectrons:
            if (ele.pt() > self.cfg_ana.veto_electron_pt
                    and abs(ele.eta()) < self.cfg_ana.veto_electron_eta and
                (abs(ele.dxy()) <
                 (self.cfg_ana.veto_electron_dxy[0] if ele.isEB() else
                  self.cfg_ana.veto_electron_dxy[1]) and abs(ele.dz()) <
                 (self.cfg_ana.veto_electron_dz[0] if ele.isEB() else
                  self.cfg_ana.veto_electron_dxy[1])) and self.eleIsoCut(ele)
                    and ele.passConversionVeto() and ele.lostInner() <=
                (self.cfg_ana.veto_electron_lostHits[0]
                 if ele.isEB() else self.cfg_ana.veto_electron_lostHits[1])
                    and (True if getattr(self.cfg_ana, 'notCleaningElectrons',
                                         False) else
                         (bestMatch(ele, vetoMuons)[1] >
                          (self.cfg_ana.min_dr_electron_muon**2)))):
                event.vetoLeptons.append(ele)
                event.vetoElectrons.append(ele)
                ele.vetoIdMonoX = True
            else:
                ele.vetoIdMonoX = False

        event.vetoLeptons.sort(key=lambda l: l.pt(), reverse=True)
        event.vetoMuons.sort(key=lambda l: l.pt(), reverse=True)
        event.vetoElectrons.sort(key=lambda l: l.pt(), reverse=True)

        for lepton in event.vetoLeptons:
            if hasattr(self, 'efficiency'):
                self.efficiency.attachToObject(lepton)
    def genMatch(self, event, leg, dR=0.3, matchAll=True):

        dR2 = dR * dR

        leg.isTauHad = False
        leg.isTauLep = False
        leg.isPromptLep = False
        leg.genp = None

        # match the tau_h leg
        # to generated had taus
        l1match, dR2best = bestMatch(leg, event.gentaus)
        if dR2best < dR2:
            leg.genp = l1match
            leg.isTauHad = True
            return

        # to generated leptons from taus
        l1match, dR2best = bestMatch(leg, self.ptSelGentauleps)
        if dR2best < dR2:
            leg.genp = l1match
            leg.isTauLep = True
            return

        # to generated prompt leptons
        l1match, dR2best = bestMatch(leg, self.ptSelGenleps)
        if dR2best < dR2:
            leg.genp = l1match
            leg.isPromptLep = True
            return

        # match with any other relevant gen particle
        if matchAll:
            l1match, dR2best = bestMatch(leg, self.ptSelGenSummary)
            if dR2best < dR2:
                leg.genp = l1match
Exemple #13
0
def MatchTausToJets(refObjs):

    # For each Jet, get the closest RecoTau
    Match = {}
    for jetidx, refObj in enumerate(refObjs):
        tau, _dr2_ = bestMatch(refObj, taus)  # dR2=0.25  ==  dR=0.5
        for tauidx, itau in enumerate(taus):
            if itau == tau: break
        if _dr2_ < 0.25: Match[jetidx] = tauidx

    # Is the same Tau assinged to more than one Jet?
    DoubleCheck = []
    for ijet, itau in Match.iteritems():
        for jjet, jtau in Match.iteritems():
            if jjet >= ijet: continue
            if itau == jtau:
                if ijet not in DoubleCheck: DoubleCheck.append(ijet)
                if jjet not in DoubleCheck: DoubleCheck.append(jjet)

    # Get all distances between all conflicting Jets and corresponding Taus
    Distances = {}
    for ijet in DoubleCheck:
        for jjet in DoubleCheck:
            itau = Match[jjet]
            Distances[str(ijet) + "_" + str(itau)] = deltaR(
                taus[itau].eta(), taus[itau].phi(), refObjs[ijet].eta(),
                refObjs[ijet].phi())
    #print Distances

    # Remove all conflicting Jets, to re-assign later
    for ijet in DoubleCheck:
        del Match[ijet]

    # Assign shortest distance between Tau and Jet, then move on ignoring the already assigned Taus/Jets
    while Distances != {}:
        keepthis = min(Distances, key=Distances.get)
        thisjet = int(keepthis[:keepthis.find("_")])
        thistau = int(keepthis[keepthis.rfind("_") + 1:])
        Match[thisjet] = thistau
        deletethis = []
        for element in Distances:
            if element.startswith(str(thisjet)) or element.endswith(
                    str(thistau)):
                deletethis.append(element)
        for element in deletethis:
            del Distances[element]

    return Match
    def makeVetoLeptons(self, event):
        ### selected leptons = subset of inclusive leptons passing some basic id definition and pt requirement
        ### other    leptons = subset of inclusive leptons failing some basic id definition and pt requirement
        event.vetoLeptons = []
        event.vetoMuons = []
        event.vetoElectrons = []

        #the selected leptons are the ones with the corrections / calibrations applied
        # make veto leptons 
        for mu in event.selectedMuons:
            if (mu.pt() > self.cfg_ana.veto_muon_pt and abs(mu.eta()) < self.cfg_ana.veto_muon_eta and 
                abs(mu.dxy()) < self.cfg_ana.veto_muon_dxy and abs(mu.dz()) < self.cfg_ana.veto_muon_dz and
                self.muIsoCut(mu)):
                    mu.vetoIdMonoX = True
                    event.vetoLeptons.append(mu)
                    event.vetoMuons.append(mu)
            else:
                    mu.vetoIdMonoX = False
        vetoMuons = event.vetoLeptons[:]
        for ele in event.selectedElectrons:
            if ( ele.pt() > self.cfg_ana.veto_electron_pt and abs(ele.eta())<self.cfg_ana.veto_electron_eta and 
                 (abs(ele.dxy()) < (self.cfg_ana.veto_electron_dxy[0] if ele.isEB() else self.cfg_ana.veto_electron_dxy[1]) and 
                  abs(ele.dz()) < (self.cfg_ana.veto_electron_dz[0]  if ele.isEB() else self.cfg_ana.veto_electron_dxy[1])) and 
                 self.eleIsoCut(ele) and 
                 ele.passConversionVeto() and ele.lostInner() <= (self.cfg_ana.veto_electron_lostHits[0] if ele.isEB() else self.cfg_ana.veto_electron_lostHits[1]) and
                 ( True if getattr(self.cfg_ana,'notCleaningElectrons',False) else (bestMatch(ele, vetoMuons)[1] > (self.cfg_ana.min_dr_electron_muon**2)) )):
                    event.vetoLeptons.append(ele)
                    event.vetoElectrons.append(ele)
                    ele.vetoIdMonoX = True
            else:
                    ele.vetoIdMonoX = False

        event.vetoLeptons.sort(key = lambda l : l.pt(), reverse = True)
        event.vetoMuons.sort(key = lambda l : l.pt(), reverse = True)
        event.vetoElectrons.sort(key = lambda l : l.pt(), reverse = True)

        for lepton in event.vetoLeptons:
            if hasattr(self,'efficiency'):
                self.efficiency.attachToObject(lepton)
Exemple #15
0
    def process(self, event):

        self.counters.counter('LegTriggerMatcher').inc('all events')

        dR2max = getattr(self.cfg_ana, 'dRmax', 0.1)**2
        collection = getattr(event, self.cfg_ana.collection)
        tomatch = self.cfg_ana.paths_and_filters
        
        for icoll in collection:
            if not hasattr(icoll, 'trig_obj'):
                icoll.trig_obj = OrderedDict()
        
        for ihlt, ifilter in tomatch.iteritems():
            infos = [info for info in event.trigger_infos if ihlt=='_'.join(info.name.split('_')[:-1])]
            if len(infos)!=1:
                continue 
            else:
                info = infos[0]           
            objects = info.objects

            objects = [obj for obj in objects if obj.filter(ifilter[0]) and obj.triggerObjectTypes()[0]==ifilter[1]]
            
            # temporary collection to save only trig matched objects
            tmp_coll = []
                   
            for icoll in collection:
                icoll.trig_obj[ifilter] = -1
                bestmatch, dR2 = bestMatch(icoll, objects)
                if dR2 < dR2max:
                    icoll.trig_obj[ifilter] = bestmatch
                    tmp_coll.append(icoll)
                
        if getattr(self.cfg_ana, 'filter', False):
            setattr(event, self.cfg_ana.collection + '_matched', tmp_coll)
    
        if len(tmp_coll)>0:
            self.counters.counter('LegTriggerMatcher').inc('matched events')

            
Exemple #16
0
    #### Fill tree ####
    tree.kaonCharged = abs_final_part.count(321)
    tree.pionCharged = abs_final_part.count(211)
    tree.kaonNeutrals = abs_final_part.count(130)+abs_final_part.count(310)
    tree.pionNeutrals = abs_final_part.count(111)
    tree.muons = abs_final_part.count(13)
    tree.electrons = abs_final_part.count(11)
    tree.neutrals = abs_final_part.count(130)+abs_final_part.count(310)+abs_final_part.count(111)+abs_final_part.count(16)+abs_final_part.count(14)+abs_final_part.count(12)
    tree.charged = abs_final_part.count(321)+abs_final_part.count(211)+abs_final_part.count(13)+abs_final_part.count(11)
    tree.dMeson = dMeson

    ####### Let's match the jets #######

    jets = [jet for jet in recoJets]
    matchedJet, _ = bestMatch(maj_neutrinos[0], jets)

    #pt eta phi mass btagging discriminator #isolamento
    #B tagging discriminator: look for displaced vertexes and traks in a jet
    if matchedJet:
        tree.pt_Jet = matchedJet.pt()
        tree.eta_Jet= matchedJet.eta()
        tree.phi_Jet= matchedJet.phi()
        tree.mass_Jet= matchedJet.mass()
        tree.et_Jet= matchedJet.et()
        
        jet_particles =  matchedJet.getPFConstituents()
        deposits = [0]*9
        for prt in jet_particles:
            dr = deltaR(prt, matchedJet)
            idx = min(int(floor(dr/0.05)), 8)
Exemple #17
0
    def makeLeptons(self, event):
        ### inclusive leptons = all leptons that could be considered somewhere in the analysis, with minimal requirements (used e.g. to match to MC)
        event.inclusiveLeptons = []
        ### selected leptons = subset of inclusive leptons passing some basic id definition and pt requirement
        ### other    leptons = subset of inclusive leptons failing some basic id definition and pt requirement
        event.selectedLeptons = []
        event.selectedMuons = []
        event.selectedElectrons = []
        event.otherLeptons = []

        if self.doMiniIsolation:
            self.IsolationComputer.setPackedCandidates(self.handles['packedCandidates'].product())
            if self.miniIsolationVetoLeptons == "any":
                for lep in self.handles['muons'].product(): 
                    self.IsolationComputer.addVeto(lep)
                for lep in self.handles['electrons'].product(): 
                    self.IsolationComputer.addVeto(lep)

        #muons
        allmuons = self.makeAllMuons(event)

        #electrons        
        allelectrons = self.makeAllElectrons(event)

        #make inclusive leptons
        inclusiveMuons = []
        inclusiveElectrons = []
        for mu in allmuons:
            if (mu.track().isNonnull() and mu.muonID(self.cfg_ana.inclusive_muon_id) and 
                    mu.pt()>self.cfg_ana.inclusive_muon_pt and abs(mu.eta())<self.cfg_ana.inclusive_muon_eta and 
                    abs(mu.dxy())<self.cfg_ana.inclusive_muon_dxy and abs(mu.dz())<self.cfg_ana.inclusive_muon_dz):
                inclusiveMuons.append(mu)
        for ele in allelectrons:
            if ( ele.electronID(self.cfg_ana.inclusive_electron_id) and
                    ele.pt()>self.cfg_ana.inclusive_electron_pt and abs(ele.eta())<self.cfg_ana.inclusive_electron_eta and 
                    abs(ele.dxy())<self.cfg_ana.inclusive_electron_dxy and abs(ele.dz())<self.cfg_ana.inclusive_electron_dz and 
                    ele.lostInner()<=self.cfg_ana.inclusive_electron_lostHits ):
                inclusiveElectrons.append(ele)
        event.inclusiveLeptons = inclusiveMuons + inclusiveElectrons
 
        if self.doMiniIsolation:
            if self.miniIsolationVetoLeptons == "inclusive":
                for lep in event.inclusiveLeptons: 
                    self.IsolationComputer.addVeto(lep)
            for lep in event.inclusiveLeptons:
                self.attachMiniIsolation(lep)

        # make loose leptons (basic selection)
        for mu in inclusiveMuons:
                if (mu.muonID(self.cfg_ana.loose_muon_id) and 
                        mu.pt() > self.cfg_ana.loose_muon_pt and abs(mu.eta()) < self.cfg_ana.loose_muon_eta and 
                        abs(mu.dxy()) < self.cfg_ana.loose_muon_dxy and abs(mu.dz()) < self.cfg_ana.loose_muon_dz and
                        self.muIsoCut(mu)):
                    mu.looseIdSusy = True
                    event.selectedLeptons.append(mu)
                    event.selectedMuons.append(mu)
                else:
                    mu.looseIdSusy = False
                    event.otherLeptons.append(mu)
        looseMuons = event.selectedLeptons[:]
        for ele in inclusiveElectrons:
               if (ele.electronID(self.cfg_ana.loose_electron_id) and
                         ele.pt()>self.cfg_ana.loose_electron_pt and abs(ele.eta())<self.cfg_ana.loose_electron_eta and 
                         abs(ele.dxy()) < self.cfg_ana.loose_electron_dxy and abs(ele.dz())<self.cfg_ana.loose_electron_dz and 
                         self.eleIsoCut(ele) and 
                         ele.lostInner() <= self.cfg_ana.loose_electron_lostHits and
                         ( True if getattr(self.cfg_ana,'notCleaningElectrons',False) else (bestMatch(ele, looseMuons)[1] > (self.cfg_ana.min_dr_electron_muon**2)) )):
                    event.selectedLeptons.append(ele)
                    event.selectedElectrons.append(ele)
                    ele.looseIdSusy = True
               else:
                    event.otherLeptons.append(ele)
                    ele.looseIdSusy = False

        event.otherLeptons.sort(key = lambda l : l.pt(), reverse = True)
        event.selectedLeptons.sort(key = lambda l : l.pt(), reverse = True)
        event.selectedMuons.sort(key = lambda l : l.pt(), reverse = True)
        event.selectedElectrons.sort(key = lambda l : l.pt(), reverse = True)
        event.inclusiveLeptons.sort(key = lambda l : l.pt(), reverse = True)

        for lepton in event.selectedLeptons:
            if hasattr(self,'efficiency'):
                self.efficiency.attachToObject(lepton)
    def genMatch(event, leg, ptSelGentauleps, ptSelGenleps, ptSelGenSummary, dR=0.3, matchAll=True):

        dR2 = dR * dR

        leg.isTauHad = False
        leg.isTauLep = False
        leg.isPromptLep = False
        leg.genp = None

        # match the tau_h leg
        # to generated had taus
        l1match, dR2best = bestMatch(leg, event.gentaus)
        if dR2best < dR2:
            leg.genp = l1match
            leg.isTauHad = True
            return

        # to generated leptons from taus
        l1match, dR2best = bestMatch(leg, ptSelGentauleps)
        if dR2best < dR2:
            leg.genp = l1match
            leg.isTauLep = True
            return

        # to generated prompt leptons
        l1match, dR2best = bestMatch(leg, ptSelGenleps)
        if dR2best < dR2:
            leg.genp = l1match
            leg.isPromptLep = True
            return

        # match with any other relevant gen particle
        if matchAll:
            l1match, dR2best = bestMatch(leg, ptSelGenSummary)
            if dR2best < dR2:
                leg.genp = l1match
                return

            # Ok do one more Pythia 8 trick...
            # This is to overcome that the GenAnalyzer doesn't like particles
            # that have daughters with same pdgId and status 71
            if not hasattr(event, "pythiaQuarksGluons"):
                event.pythiaQuarksGluons = []
                for gen in event.genParticles:
                    pdg = abs(gen.pdgId())
                    status = gen.status()
                    if pdg in [1, 2, 3, 4, 5, 21] and status > 3:
                        if gen.isMostlyLikePythia6Status3():
                            event.pythiaQuarksGluons.append(gen)

            l1match, dR2best = bestMatch(leg, event.pythiaQuarksGluons)
            if dR2best < dR2:
                leg.genp = l1match
                return

            # Now this may be a pileup lepton, or one whose ancestor doesn't
            # appear in the gen summary because it's an unclear case in Pythia 8
            # To check the latter, match against jets as well...
            l1match, dR2best = bestMatch(leg, event.genJets)
            # Check if there's a gen jet with pT > 10 GeV (otherwise it's PU)
            if dR2best < dR2 and l1match.pt() > 10.0:
                leg.genp = PhysicsObject(l1match)

                jet, dR2best = bestMatch(l1match, event.jets)

                if dR2best < dR2:
                    leg.genp.detFlavour = jet.partonFlavour()
                else:
                    print "no match found", leg.pt(), leg.eta()
Exemple #19
0
    def process(self, event):
        self.readCollections(event.input)
        self.counters.counter('RecoGenTreeAnalyzer').inc('all events')

        # produce collections and map our objects to convenient Heppy objects
        event.muons = map(Muon, self.handles['muons'].product())
        event.electrons = map(Electron, self.handles['electrons'].product())
        event.photons = map(Photon, self.handles['photons'].product())
        event.taus = map(Tau, self.handles['taus'].product())
        event.jets = map(Jet, self.handles['jets'].product())
        event.dsmuons = self.buildDisplacedMuons(
            self.handles['dsmuons'].product())
        event.dgmuons = self.buildDisplacedMuons(
            self.handles['dgmuons'].product())

        # vertex stuff
        event.pvs = self.handles['pvs'].product()
        event.svs = self.handles['svs'].product()
        event.beamspot = self.handles['beamspot'].product()

        # met
        event.met = self.handles['met'].product().at(0)

        # assign to the leptons the primary vertex, will be needed to compute a few quantities
        # FIXME! understand exactly to which extent it is reasonable to assign the PV to *all* leptons
        #        regardless whether they're displaced or not
        if len(event.pvs):
            myvtx = event.pvs[0]
        else:
            myvtx = event.beamspot

        self.assignVtx(event.muons, myvtx)
        self.assignVtx(event.electrons, myvtx)
        self.assignVtx(event.photons, myvtx)
        self.assignVtx(event.taus, myvtx)

        # all matchable objects
        #         matchable = event.electrons + event.photons + event.muons + event.taus + event.dsmuons + event.dgmuons
        #         matchable = event.electrons + event.photons + event.muons + event.taus + event.dsmuons
        # matchable = event.electrons + event.photons + event.taus + event.muons + event.dsmuons + event.dgmuons
        matchable = event.electrons + event.photons + event.taus + event.muons

        #define the dr to cut on
        dr_cut = 0.2

        # match gen to reco
        for ip in [event.the_hnl.l0(), event.the_hnl.l1(), event.the_hnl.l2()]:
            ip.bestmatch = None
            ip.bestmatchtype = None
            ip.matches = inConeCollection(
                ip, matchable, getattr(self.cfg_ana, 'drmax', dr_cut), 0.)

            # matches the corresponding "slimmed electron" to the gen particle
            if len(event.electrons):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.electrons)
                if dr2 < dr_cut * dr_cut:
                    ip.bestelectron = match

            # # matches the corresponding "slimmed photon" to the gen particle
            # if len(event.photons):
            # dr2 = np.inf
            # match, dr2 = bestMatch(ip,event.photons)
            # if dr2 < dr_cut * dr_cut:
            # ip.bestphoton = match

            # matches the corresponding "slimmed muon" to the gen particle
            if len(event.muons):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.muons)
                if dr2 < dr_cut * dr_cut:
                    ip.bestmuon = match

            # # matches the corresponding "slimmed tau" to the gen particle
            # if len(event.taus):
            # dr2 = np.inf
            # match, dr2 = bestMatch(ip,event.taus)
            # if dr2 < dr_cut * dr_cut:
            # ip.besttau = match

            # matches the corresponding "displaced stand alone muon" to the gen particle
            if len(event.dsmuons):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.dsmuons)
                if dr2 < dr_cut * dr_cut:
                    ip.bestdsmuon = match

            # matches the corresponding "displaced global muon" to the gen particle
            if len(event.dgmuons):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.dgmuons)
                if dr2 < dr_cut * dr_cut:
                    ip.bestdgmuon = match

            # to find the best match, give precedence to any matched
            # particle in the matching cone with the correct PDG ID
            # then to the one which is closest
            ip.matches.sort(key=lambda x:
                            (x.pdgId() == ip.pdgId(), -deltaR(x, ip)),
                            reverse=True)

            if len(ip.matches) and abs(ip.pdgId()) == abs(
                    ip.matches[0].pdgId()):
                ip.bestmatch = ip.matches[0]
                ip.bestmatchdR = deltaR(ip, ip.bestmatch)
                # remove already matched particles, avoid multiple matches to the same candidate while recording the type of reconstruction
                matchable.remove(ip.bestmatch)

                # record which is which
                if ip.bestmatch in event.electrons: ip.bestmatchtype = 11
                if ip.bestmatch in event.photons: ip.bestmatchtype = 22
                if ip.bestmatch in event.muons: ip.bestmatchtype = 13
                if ip.bestmatch in event.taus: ip.bestmatchtype = 15
                if ip.bestmatch in event.dsmuons: ip.bestmatchtype = 26
                if ip.bestmatch in event.dgmuons: ip.bestmatchtype = 39

            else:
                ip.bestmatchtype = -1

        # clear it before doing it again
        event.recoSv = None

        # let's refit the secondary vertex, IF both leptons match to some reco particle
        pair = [event.the_hnl.l1().bestmatch, event.the_hnl.l2().bestmatch]
        if (pair[0] != None) and\
           (pair[1] != None) and\
           (pair[0].physObj != pair[1].physObj):

            event.recoSv = fitVertex(pair)

            if event.recoSv:
                # primary vertex
                pv = event.goodVertices[0]

                event.recoSv.disp3DFromBS = ROOT.VertexDistance3D().distance(
                    event.recoSv, pv)
                event.recoSv.disp3DFromBS_sig = event.recoSv.disp3DFromBS.significance(
                )

                # create an 'ideal' vertex out of the BS
                point = ROOT.reco.Vertex.Point(
                    event.beamspot.position().x(),
                    event.beamspot.position().y(),
                    event.beamspot.position().z(),
                )
                error = event.beamspot.covariance3D()
                chi2 = 0.
                ndof = 0.
                bsvtx = ROOT.reco.Vertex(point, error, chi2, ndof,
                                         2)  # size? say 3? does it matter?

                event.recoSv.disp2DFromBS = ROOT.VertexDistanceXY().distance(
                    event.recoSv, bsvtx)
                event.recoSv.disp2DFromBS_sig = event.recoSv.disp2DFromBS.significance(
                )
                event.recoSv.prob = ROOT.TMath.Prob(event.recoSv.chi2(),
                                                    int(event.recoSv.ndof()))

                dilep_p4 = event.the_hnl.l1().bestmatch.p4(
                ) + event.the_hnl.l2().bestmatch.p4()

                perp = ROOT.math.XYZVector(dilep_p4.px(), dilep_p4.py(), 0.)

                dxybs = ROOT.GlobalPoint(
                    -1 * ((event.beamspot.x0() - event.recoSv.x()) +
                          (event.recoSv.z() - event.beamspot.z0()) *
                          event.beamspot.dxdz()),
                    -1 * ((event.beamspot.y0() - event.recoSv.y()) +
                          (event.recoSv.z() - event.beamspot.z0()) *
                          event.beamspot.dydz()), 0)

                vperp = ROOT.math.XYZVector(dxybs.x(), dxybs.y(), 0.)

                cos = vperp.Dot(perp) / (vperp.R() * perp.R())

                event.recoSv.disp2DFromBS_cos = cos

        return True
            '<ROOT::Math::PtEtaPhiM4D<double> >')()
        for idau in xrange(itau.numberOfDaughters()):
            if abs(itau.daughter(idau).pdgId()) not in [12, 14, 16]:
                itau_vis += itau.daughter(idau).p4()

        # gen decay mode
        itau.gen_dm = tauDecayModes.genDecayModeInt([
            d for d in finalDaughters(itau)
            if abs(d.pdgId()) not in [12, 14, 16]
        ])

        # reco tau
        reco_tau = None
        match = None
        dr2 = 1e3
        match, dr2 = bestMatch(itau_vis, event.taus)

        if dr2 < 0.2 * 0.2:
            reco_tau = match

        # reco tau
        reco_tau_bis = None
        match = None
        dr2 = 1e3
        match, dr2 = bestMatch(itau_vis, event.taus_bis)

        if dr2 < 0.2 * 0.2:
            reco_tau_bis = match

        # identify the primary vertex
        event.the_pv = event.the_hn.vertex()
    def genMatch(event, leg, ptSelGentauleps, ptSelGenleps, ptSelGenSummary, 
                 dR=0.2, matchAll=True):

        dR2 = dR * dR

        leg.isTauHad = False
        leg.isTauLep = False
        leg.isPromptLep = False
        leg.genp = None

        best_dr2 = dR2

        # The following would work for pat::Taus, but we also want to flag a 
        # muon/electron as coming from a hadronic tau with the usual definition
        # if this happens

        # if hasattr(leg, 'genJet') and leg.genJet():
        #     if leg.genJet().pt() > 15.:
        #         dr2 = deltaR2(leg.eta(), leg.phi(), leg.genJet().eta(), leg.genJet().phi())
        #         if dr2 < best_dr2:
        #             best_dr2 = dr2
        #             leg.genp = leg.genJet()
        #             leg.genp.setPdgId(-15 * leg.genp.charge())
        #             leg.isTauHad = True
        
        # RM: needed to append genTauJets to the events,
        #     when genMatch is used as a static method
        if not hasattr(event, 'genTauJets'):
            HTTGenAnalyzer.getGenTauJets(event)

        l1match, dR2best = bestMatch(leg, event.genTauJets)
        if dR2best < best_dr2:
            best_dr2 = dR2best
            # leg.genp = GenParticle(l1match)
            leg.genp = l1match
            leg.genp.setPdgId(-15 * leg.genp.charge())
            leg.isTauHad = True
            # if not leg.genJet():
            #     print 'Warning, tau does not have matched gen tau'
            # elif leg.genJet().pt() < 15.:
            #     print 'Warning, tau has matched gen jet but with pt =', leg.genJet().pt()

        # to generated leptons from taus
        l1match, dR2best = bestMatch(leg, ptSelGentauleps)
        if dR2best < best_dr2:
            best_dr2 = dR2best
            leg.genp = l1match
            leg.isTauLep = True
            leg.isTauHad = False

        # to generated prompt leptons
        l1match, dR2best = bestMatch(leg, ptSelGenleps)
        if dR2best < best_dr2:
            best_dr2 = dR2best
            leg.genp = l1match
            leg.isPromptLep = True
            leg.isTauLep = False
            leg.isTauHad = False

        if best_dr2 < dR2:
            return

        # match with any other relevant gen particle
        if matchAll:
            l1match, dR2best = bestMatch(leg, ptSelGenSummary)
            if dR2best < best_dr2:
                leg.genp = l1match
                return

            # Ok do one more Pythia 8 trick...
            # This is to overcome that the GenAnalyzer doesn't like particles
            # that have daughters with same pdgId and status 71
            if not hasattr(event, 'pythiaQuarksGluons'):
                event.pythiaQuarksGluons = []
                for gen in event.genParticles:
                    pdg = abs(gen.pdgId())
                    status = gen.status()
                    if pdg in [1, 2, 3, 4, 5, 21] and status > 3:
                        if gen.isMostlyLikePythia6Status3():
                            event.pythiaQuarksGluons.append(gen)

            
            l1match, dR2best = bestMatch(leg, event.pythiaQuarksGluons)
            if dR2best < best_dr2:
                leg.genp = l1match
                return

            # Now this may be a pileup lepton, or one whose ancestor doesn't
            # appear in the gen summary because it's an unclear case in Pythia 8
            # To check the latter, match against jets as well...
            l1match, dR2best = bestMatch(leg, getattr(event, 'genJets', []))
            # Check if there's a gen jet with pT > 10 GeV (otherwise it's PU)
            if dR2best < dR2 and l1match.pt() > 10.:
                leg.genp = PhysicsObject(l1match)

                jet, dR2best = bestMatch(l1match, event.jets)

                if dR2best < dR2:
                    leg.genp.detFlavour = jet.partonFlavour()
                else:
                    print 'no match found', leg.pt(), leg.eta()
    def genMatch(event,
                 leg,
                 ptSelGentauleps,
                 ptSelGenleps,
                 ptSelGenSummary,
                 dR=0.2,
                 matchAll=True):

        dR2 = dR * dR

        leg.isTauHad = False
        leg.isTauLep = False
        leg.isPromptLep = False
        leg.genp = None

        best_dr2 = dR2
        # if hasattr(leg, 'genJet') and leg.genJet():
        #     if leg.genJet().pt() > 15.:
        #         dr2 = deltaR2(leg.eta(), leg.phi(), leg.genJet().eta(), leg.genJet().phi())
        #         if dr2 < best_dr2:
        #             best_dr2 = dr2
        #             leg.genp = leg.genJet()
        #             leg.genp.setPdgId(-15 * leg.genp.charge())
        #             leg.isTauHad = True

        l1match, dR2best = bestMatch(leg, event.genTauJets)
        if dR2best < best_dr2:
            best_dr2 = dR2best
            leg.genp = GenParticle(l1match)
            leg.genp.setPdgId(-15 * leg.genp.charge())
            leg.isTauHad = True

        # to generated leptons from taus
        l1match, dR2best = bestMatch(leg, ptSelGentauleps)
        if dR2best < best_dr2:
            best_dr2 = dR2best
            leg.genp = l1match
            leg.isTauLep = True
            leg.isTauHad = False

        # to generated prompt leptons
        l1match, dR2best = bestMatch(leg, ptSelGenleps)
        if dR2best < best_dr2:
            best_dr2 = dR2best
            leg.genp = l1match
            leg.isPromptLep = True
            leg.isTauLep = False
            leg.isTauHad = False

        if best_dr2 < dR2:
            return

        # match with any other relevant gen particle
        if matchAll:
            l1match, dR2best = bestMatch(leg, ptSelGenSummary)
            if dR2best < best_dr2:
                leg.genp = l1match
                return

            # Ok do one more Pythia 8 trick...
            # This is to overcome that the GenAnalyzer doesn't like particles
            # that have daughters with same pdgId and status 71
            if not hasattr(event, 'pythiaQuarksGluons'):
                event.pythiaQuarksGluons = []
                for gen in event.genParticles:
                    pdg = abs(gen.pdgId())
                    status = gen.status()
                    if pdg in [1, 2, 3, 4, 5, 21] and status > 3:
                        if gen.isMostlyLikePythia6Status3():
                            event.pythiaQuarksGluons.append(gen)

            l1match, dR2best = bestMatch(leg, event.pythiaQuarksGluons)
            if dR2best < best_dr2:
                leg.genp = l1match
                return

            # Now this may be a pileup lepton, or one whose ancestor doesn't
            # appear in the gen summary because it's an unclear case in Pythia 8
            # To check the latter, match against jets as well...
            l1match, dR2best = bestMatch(leg, event.genJets)
            # Check if there's a gen jet with pT > 10 GeV (otherwise it's PU)
            if dR2best < dR2 and l1match.pt() > 10.:
                leg.genp = PhysicsObject(l1match)

                jet, dR2best = bestMatch(l1match, event.jets)

                if dR2best < dR2:
                    leg.genp.detFlavour = jet.partonFlavour()
                else:
                    print 'no match found', leg.pt(), leg.eta()
Exemple #23
0
                            final_particles_pi0.append(p)
                    else:
                        final_particles.append(p)


    tree.numbOfDaughters =  len(final_particles)
    muon_gen = [(x,x.pt()) for x in final_particles if (abs(x.pdgId())==13)]
    muon_gen.sort(key=lambda tup: tup[1], reverse=True) 


    ####### Let's match the jets #######

    jets = [jet for jet in recoJets if jet.pt() > 20]
    #print len(jets)
    if len(jets)!=0:
        jet_HNL, deltaR_HNL = bestMatch(maj_neutrinos[0], jets)

        tree.deltaR_HNL = deltaR_HNL
    #tree.jet_HNL_p = jet_HNL.p()
        tree.jet_HNL_pt = jet_HNL.pt()
        tree.jet_HNL_eta = jet_HNL.eta()
        tree.jet_HNL_phi = jet_HNL.phi()

    #let's check the fraction of the HNL daughters within a cone of .4 from the jet axes
        daughter_deltaR_HNL = []
        for part in final_particles: 
            daughter_deltaR_HNL.append(deltaR(part,jet_HNL))
        tree.frac_HNLjet = float(sum(i < 0.4 for i in daughter_deltaR_HNL))/float(len(daughter_deltaR_HNL))
        
    
        matchJetlist =  bestMatchedJet(muon_gen[0][0], jets)
Exemple #24
0
    def makeLeptons(self, event):
        ### inclusive leptons = all leptons that could be considered somewhere in the analysis, with minimal requirements (used e.g. to match to MC)
        event.inclusiveLeptons = []
        ### selected leptons = subset of inclusive leptons passing some basic id definition and pt requirement
        ### other    leptons = subset of inclusive leptons failing some basic id definition and pt requirement
        event.selectedLeptons = []
        event.selectedMuons = []
        event.selectedElectrons = []
        event.otherLeptons = []

        #muons
        allmuons = self.makeAllMuons(event)

        for mu in allmuons:
            # inclusive, very loose, selection
            if (mu.track().isNonnull() and mu.muonID(self.cfg_ana.inclusive_muon_id) and 
                    mu.pt()>self.cfg_ana.inclusive_muon_pt and abs(mu.eta())<self.cfg_ana.inclusive_muon_eta and 
                    abs(mu.dxy())<self.cfg_ana.inclusive_muon_dxy and abs(mu.dz())<self.cfg_ana.inclusive_muon_dz):
                event.inclusiveLeptons.append(mu)
                # basic selection
                if (mu.muonID(self.cfg_ana.loose_muon_id) and 
                        mu.pt() > self.cfg_ana.loose_muon_pt and abs(mu.eta()) < self.cfg_ana.loose_muon_eta and 
                        abs(mu.dxy()) < self.cfg_ana.loose_muon_dxy and abs(mu.dz()) < self.cfg_ana.loose_muon_dz and
                        mu.relIso03 < self.cfg_ana.loose_muon_relIso and 
                        mu.absIso03 < (self.cfg_ana.loose_muon_absIso if hasattr(self.cfg_ana,'loose_muon_absIso') else 9e99)):
                    mu.looseIdSusy = True
                    event.selectedLeptons.append(mu)
                    event.selectedMuons.append(mu)
                else:
                    mu.looseIdSusy = False
                    event.otherLeptons.append(mu)

        #electrons        
        allelectrons = self.makeAllElectrons(event)

        looseMuons = event.selectedLeptons[:]
        for ele in allelectrons:
            ## remove muons if muForEleCrossCleaning is not empty
            ## apply selection
            if ( ele.electronID(self.cfg_ana.inclusive_electron_id) and
                    ele.pt()>self.cfg_ana.inclusive_electron_pt and abs(ele.eta())<self.cfg_ana.inclusive_electron_eta and 
                    abs(ele.dxy())<self.cfg_ana.inclusive_electron_dxy and abs(ele.dz())<self.cfg_ana.inclusive_electron_dz and 
                    ele.lostInner()<=self.cfg_ana.inclusive_electron_lostHits ):
                event.inclusiveLeptons.append(ele)
                # basic selection
                if (ele.electronID(self.cfg_ana.loose_electron_id) and
                         ele.pt()>self.cfg_ana.loose_electron_pt and abs(ele.eta())<self.cfg_ana.loose_electron_eta and 
                         abs(ele.dxy()) < self.cfg_ana.loose_electron_dxy and abs(ele.dz())<self.cfg_ana.loose_electron_dz and 
                         ele.relIso03 <= self.cfg_ana.loose_electron_relIso and
                         ele.absIso03 < (self.cfg_ana.loose_electron_absIso if hasattr(self.cfg_ana,'loose_electron_absIso') else 9e99) and
                         ele.lostInner() <= self.cfg_ana.loose_electron_lostHits and
                         ( True if (hasattr(self.cfg_ana,'notCleaningElectrons') and self.cfg_ana.notCleaningElectrons) else (bestMatch(ele, looseMuons)[1] > self.cfg_ana.min_dr_electron_muon) )):
                    event.selectedLeptons.append(ele)
                    event.selectedElectrons.append(ele)
                    ele.looseIdSusy = True
                else:
                    event.otherLeptons.append(ele)
                    ele.looseIdSusy = False

        event.otherLeptons.sort(key = lambda l : l.pt(), reverse = True)
        event.selectedLeptons.sort(key = lambda l : l.pt(), reverse = True)
        event.selectedMuons.sort(key = lambda l : l.pt(), reverse = True)
        event.selectedElectrons.sort(key = lambda l : l.pt(), reverse = True)
        event.inclusiveLeptons.sort(key = lambda l : l.pt(), reverse = True)

        for lepton in event.selectedLeptons:
            if hasattr(self,'efficiency'):
                self.efficiency.attachToObject(lepton)
                    d for d in finalDaughters(refObj)
                    if abs(d.pdgId()) not in [12, 14, 16]
                ])
                all_var_dict['tau_gendm'].fill(gen_dm)
                all_var_dict['tau_gendm_rough'].fill(returnRough(gen_dm))
                all_var_dict['tau_genpt'].fill(visP4.pt())
                all_var_dict['tau_geneta'].fill(visP4.eta())
                all_var_dict['tau_genphi'].fill(visP4.phi())
            else:
                all_var_dict['tau_gendm'].fill(-1)
                all_var_dict['tau_gendm_rough'].fill(-1)
                all_var_dict['tau_genpt'].fill(refObj.pt())
                all_var_dict['tau_geneta'].fill(refObj.eta())
                all_var_dict['tau_genphi'].fill(refObj.phi())

            tau, _dr_ = bestMatch(refObj, taus)
            if _dr_ > 0.5:
                tau = None

            tau_vtxTovtx_dz = 99
            for i in range(0, len(vertices) - 1):
                for j in range(i + 1, len(vertices)):
                    vtxdz = abs(vertices[i].z() - vertices[j].z())
                    if vtxdz < tau_vtxTovtx_dz:
                        tau_vtxTovtx_dz = vtxdz
            all_var_dict['tau_vtxTovtx_dz'].fill(tau_vtxTovtx_dz)

            # Fill reco-tau variables if it exists...
            if tau != None:

                all_var_dict['tau_dm'].fill(tau.decayMode())
Exemple #26
0
    def process(self, event):
        if not self.enable:
            self.dummyProcess(event)
            return True

        self.readCollections( event.input )
        pf = self.handles['pf'].product()
        leptons = getattr(event,self.leptonTag)
        self.IsolationComputer.setPackedCandidates(self.handles['pf'].product())

        forIso = []
        for ipf,p in enumerate(pf):
            if p.pdgId() != 22 or not( p.pt() > 2.0 and abs(p.eta()) < 2.4 ):
                continue
            if self.cfg_ana.electronVeto != None:
              scVetoed = False
              for l in leptons:
                if abs(l.pdgId())==11 and self.electronID(l):
                    #print "Testing photon pt %5.1f eta %+7.4f phi %+7.4f vs ele pt %.1f eta %+7.4f  phi %+7.4f sc  eta %+7.4f  phi %+7.4f" % ( p.pt(), p.eta(), p.phi(), l.pt(), l.eta(), l.phi(), l.superCluster().eta(), l.superCluster().phi() )
                    #print "Testing                                                       deta %+7.4f dphi %+7.4f sc deta %+7.4f dphi %+7.4f" % ( abs(p.eta()-l.eta()), deltaPhi(p.phi(),l.phi()), abs(p.eta()-l.superCluster().eta()), deltaPhi(p.phi(),l.superCluster().phi()))
                    if self.cfg_ana.electronVeto == "superclusterEta":
                        if (abs(p.eta()-l.superCluster().eta())<0.05 and abs(deltaPhi(p.phi(),l.superCluster().phi()))<2) or deltaR(p.eta(),p.phi(),l.superCluster().eta(),l.superCluster().phi())<0.15: 
                            scVetoed = True; break
                    elif self.cfg_ana.electronVeto == "electronEta":
                        if (abs(p.eta()-l.eta())<0.05 and abs(deltaPhi(p.phi(),l.phi()))<2) or deltaR(p.eta(),p.phi(),l.eta(),l.phi())<0.15: 
                            scVetoed = True; break
                    elif self.cfg_ana.electronVeto == "pfCandReference":
                        pfcrefs = l.associatedPackedPFCandidates()
                        for iref in xrange(pfcrefs.size()):
                            pfcref = pfcrefs[iref] 
                            if pfcref.key() == ipf:
                                #print "Testing photon pt %5.1f eta %+7.4f phi %+7.4f " % ( p.pt(), p.eta(), p.phi() )
                                #print "  pfcand ref   pt %5.1f eta %+7.4f phi %+7.4f " % ( pfcref.get().pt(), pfcref.get().eta(), pfcref.get().phi() )
                                #print "  from elec    pt %5.1f eta %+7.4f phi %+7.4f " % ( l.pt(), l.eta(), l.phi() )
                                scVetoed = True;
                    else: 
                        raise RuntimeError, "electronVeto option %r not implemented" % self.cfg_ana.electronVeto
              if scVetoed: continue
            closestLepton, minDR2 = bestMatch(p, leptons)
            if minDR2 >= 0.5*0.5: continue
            p.globalClosestLepton = closestLepton
            forIso.append(p)

        isolatedPhotons = []
        relIsoCut = self.cfg_ana.relIsoCut        
        for g in forIso:
            g.absIsoCH = self.IsolationComputer.chargedAbsIso(g,0.3,0.0001,0.2)
            g.absIsoPU = self.IsolationComputer.puAbsIso(g,0.3,0.0001,0.2)
            g.absIsoNH = self.IsolationComputer.neutralHadAbsIsoRaw(g,0.3,0.01,0.5)
            g.absIsoPH = self.IsolationComputer.photonAbsIsoRaw(g,0.3,0.01,0.5)
            g.relIso   = (g.absIsoCH+g.absIsoPU+g.absIsoNH+g.absIsoPH)/g.pt()
            if g.relIso < relIsoCut:
                isolatedPhotons.append(g)

        event.fsrPhotonsNoIso = forIso
        event.fsrPhotonsIso   = isolatedPhotons

        event.attachedFsrPhotons = []
        drOverET2Cut = self.cfg_ana.drOverET2Cut
        for l in leptons:
            best = None
            for p in event.fsrPhotonsIso:
                if p.globalClosestLepton != l: continue
                drOverET2 = deltaR(p.eta(),p.phi(),l.eta(),l.phi())/p.et2()
                if drOverET2 >= drOverET2Cut: continue
                p.drOverET2 = drOverET2
                if best == None or best.drOverET2 > drOverET2:
                    best = p
            if best:
                event.attachedFsrPhotons.append(best)
                l.ownFsrPhotons = [ best ]
            else: 
                l.ownFsrPhotons = [ ]

        #now attach FSR photons to all leptons (for isolation)
        for l in leptons:
            l.fsrPhotons = inConeCollection(l, event.attachedFsrPhotons, 0.5, -1)
            l.relIsoAfterFSR = l.absIsoWithFSR(R=0.3)/l.pt()

        #define list of FSR photons attached to photons that pass post-FSR iso, for jet cleaning
        event.selectedPhotons = []
        for l in leptons:
            if l.tightId() and l.relIsoAfterFSR < 0.35:
                event.selectedPhotons += l.ownFsrPhotons

        return True
Exemple #27
0
    def process(self, event):
        self.readCollections(event.input)

        self.counters.counter('BKstLLGenAnalyzer').inc('all events')

        # attach qscale (pt hat) to the event
        event.qscale = self.mchandles['genInfo'].product().qScale()

        # get the tracks
        allpf = map(PhysicsObject, self.handles['pfcands'].product())
        losttracks = map(PhysicsObject, self.handles['losttracks'].product())

        # merge the track collections
        event.alltracks = sorted([
            tt for tt in allpf + losttracks
            if tt.charge() != 0 and abs(tt.pdgId()) not in (11, 13)
        ],
                                 key=lambda x: x.pt(),
                                 reverse=True)

        #         import pdb ; pdb.set_trace()

        # get the offline electrons and muons
        event.electrons = map(Electron, self.handles['electrons'].product())
        event.muons = map(Muon, self.handles['muons'].product())

        # find the gen B mesons from the hard scattering
        pruned_gen_particles = self.mchandles['prunedGenParticles'].product()
        packed_gen_particles = self.mchandles['packedGenParticles'].product()
        all_gen_particles = [ip for ip in pruned_gen_particles
                             ] + [ip for ip in packed_gen_particles]

        # match gen mu to offline mu
        genmus = [
            ii for ii in all_gen_particles
            if abs(ii.pdgId()) == 13 and ii.status() == 1
        ]
        for imu in genmus:
            bm, dr = bestMatch(imu, event.muons)
            if dr < 0.3:
                imu.reco = bm
        if len(genmus) > 0:
            event.thetagmu = sorted(genmus, key=lambda x: x.pt(),
                                    reverse=True)[0]

        # match gen ele to offline ele
        geneles = [
            ii for ii in all_gen_particles
            if abs(ii.pdgId()) == 11 and ii.status() == 1
        ]
        for iele in geneles:
            bm, dr = bestMatch(iele, event.electrons)
            if dr < 0.3:
                iele.reco = bm

        event.gen_bmesons = [
            pp for pp in pruned_gen_particles if abs(pp.pdgId()) > 500
            and abs(pp.pdgId()) < 600 and pp.isPromptDecayed()
        ]

        event.gen_b0mesons = [
            pp for pp in pruned_gen_particles if abs(pp.pdgId()) == 511
        ]

        # walk down the lineage of the B mesons and find the final state muons and charged particles
        for ip in event.gen_b0mesons + event.gen_bmesons:
            if getattr(self.cfg_ana, 'verbose', False):
                print 'PdgId : %s   pt : %s  eta : %s   phi : %s' % (
                    ip.pdgId(), ip.pt(), ip.eta(), ip.phi())
                print '     daughters'
            finaldaughters = []
            finalcharged = []
            finalmuons = []
            for ipp in packed_gen_particles:
                mother = ipp.mother(0)
                if mother and self.isAncestor(ip, mother):
                    if abs(ipp.pdgId()) == 13:
                        finalmuons.append(ipp)
                    if abs(ipp.charge()) == 1:
                        finalcharged.append(ipp)
                    if getattr(self.cfg_ana, 'verbose', False):
                        print '     PdgId : %s   pt : %s  eta : %s   phi : %s' % (
                            ipp.pdgId(), ipp.pt(), ipp.eta(), ipp.phi())
                    finaldaughters.append(ipp)
                    if getattr(self.cfg_ana, 'verbose', False):
                        print '     PdgId : %s   pt : %s  eta : %s   phi : %s' % (
                            ipp.pdgId(), ipp.pt(), ipp.eta(), ipp.phi())
            ip.finalmuondaughters = sorted(finalmuons,
                                           key=lambda x: x.pt(),
                                           reverse=True)
            ip.finalchargeddaughters = sorted(finalcharged,
                                              key=lambda x: x.pt(),
                                              reverse=True)
            ip.finaldaughters = sorted(finaldaughters,
                                       key=lambda x: x.pt(),
                                       reverse=True)

        for ib0 in event.gen_b0mesons:
            if abs(self.cfg_ana.flavour) == 11:
                togenmatchleptons = event.electrons
            elif abs(self.cfg_ana.flavour) == 13:
                togenmatchleptons = event.muons
            else:
                print 'you can only pick either pdgId 11 or 13'
                raise
            isit, lp, lm, pi, k = self.isKstLL(ib0, togenmatchleptons,
                                               event.alltracks,
                                               abs(self.cfg_ana.flavour))
            if isit:
                event.kstll = ib0
                event.kstll.lp = lp
                event.kstll.lm = lm
                event.kstll.pi = pi
                event.kstll.k = k
                event.kstll.dr = min(
                    [deltaR(event.kstll, jj) for jj in [lp, lm, pi, k]])
                break  # yeah, only one at a time, mate!

#         if hasattr(event.kstll.lp, 'reco') and hasattr(event.kstll.lm, 'reco'):
#             if event.kstll.lp.reco.pt() ==  event.kstll.lm.reco.pt():
#                 import pdb ; pdb.set_trace()

        if not hasattr(event, 'kstll'):
            return False
        self.counters.counter('BKstLLGenAnalyzer').inc(
            'has a good gen B0->K*LL')

        toclean = None

        if event.kstll.isPromptDecayed():
            toclean = event.kstll

        else:
            for ip in event.gen_bmesons:
                if self.isAncestor(ip, event.kstll):
                    toclean = ip
                    break

#         if toclean is None:
#             print 'nothing to clean lumi %d, ev %d' %(event.lumi, event.eventId)
#             return False
#             import pdb ; pdb.set_trace()
#
#         self.counters.counter('BKstLLGenAnalyzer').inc('no f**k ups')

#         elif abs(event.kstll.mother(0).pdgId())>500 and abs(event.kstll.mother(0).pdgId())<600:
#             if toclean = event.kstll.mother(0)
#         elif abs(event.kstll.mother(0).mother(0).pdgId())>500 and abs(event.kstll.mother(0).mother(0).pdgId())<600:
#         else:
#             print 'nothing to clean lumi %d, ev %d' %(event.lumi, event.eventId)
#             import pdb ; pdb.set_trace()

        if toclean is not None:
            event.clean_gen_bmesons = [
                ib for ib in event.gen_bmesons if ib != toclean
            ]
        else:
            event.clean_gen_bmesons = event.gen_bmesons

#         import pdb ; pdb.set_trace()

# now find the L1 muons from BX = 0
        L1muons_allbx = self.handles['L1muons'].product()

        L1_muons = []

        for jj in range(L1muons_allbx.size(0)):
            L1_muons.append(L1muons_allbx.at(0, jj))

        event.L1_muons = L1_muons

        event.selectedLeptons = [
        ]  # don't really care about isolated leptons, right?

        return True
Exemple #28
0
    def process(self, event):
        '''
        '''
        self.readCollections(event.input)
        self.tree.reset()
        self.event = event
        # event variables
        self.fillEvent(self.tree, event)
        self.fill(self.tree, 'n_cands', len(event.dimuonsvtx))
        self.fill(self.tree, 'rho', event.rho)

        # reco HNL
        self.fillHNL(self.tree, 'hnl', event.the_3lep_cand)
        self.fill(self.tree, 'hnl_iso03_abs_rhoArea',
                  event.the_3lep_cand.abs_tot_iso03_rhoArea)
        self.fill(self.tree, 'hnl_iso04_abs_rhoArea',
                  event.the_3lep_cand.abs_tot_iso04_rhoArea)
        self.fill(self.tree, 'hnl_iso05_abs_rhoArea',
                  event.the_3lep_cand.abs_tot_iso05_rhoArea)
        self.fill(self.tree, 'hnl_iso03_abs_deltaBeta',
                  event.the_3lep_cand.abs_tot_iso03_deltaBeta)
        self.fill(self.tree, 'hnl_iso04_abs_deltaBeta',
                  event.the_3lep_cand.abs_tot_iso04_deltaBeta)
        self.fill(self.tree, 'hnl_iso05_abs_deltaBeta',
                  event.the_3lep_cand.abs_tot_iso05_deltaBeta)
        #        self.fill    (self.tree, 'hnl_iso_abs_met'      , event.the_3lep_cand.abs_ch_iso_met  )
        self.fill(self.tree, 'hnl_iso03_rel_rhoArea',
                  event.the_3lep_cand.rel_tot_iso03_rhoArea)
        self.fill(self.tree, 'hnl_iso04_rel_rhoArea',
                  event.the_3lep_cand.rel_tot_iso04_rhoArea)
        self.fill(self.tree, 'hnl_iso05_rel_rhoArea',
                  event.the_3lep_cand.rel_tot_iso05_rhoArea)
        self.fill(self.tree, 'hnl_iso03_rel_deltaBeta',
                  event.the_3lep_cand.rel_tot_iso03_deltaBeta)
        self.fill(self.tree, 'hnl_iso04_rel_deltaBeta',
                  event.the_3lep_cand.rel_tot_iso04_deltaBeta)
        self.fill(self.tree, 'hnl_iso05_rel_deltaBeta',
                  event.the_3lep_cand.rel_tot_iso05_deltaBeta)
        #        self.fill    (self.tree, 'hnl_iso_rel_met'      , event.the_3lep_cand.rel_ch_iso_met  )
        self.fillMuon(self.tree, 'l1', event.the_3lep_cand.l1())
        self.fillMuon(self.tree, 'l2', event.the_3lep_cand.l2())
        if self.cfg_ana.promptLepType == 'ele':
            self.fillEle(self.tree, 'l0', event.the_3lep_cand.l0())
        if self.cfg_ana.promptLepType == 'mu':
            self.fillMuon(self.tree, 'l0', event.the_3lep_cand.l0())

        # output of MC analysis ONLY FOR SIGNAL
        if hasattr(event, 'the_hnl'):
            self.fillHNL(self.tree, 'hnl_gen', event.the_hnl)
            self.fillParticle(self.tree, 'l0_gen', event.the_hnl.l0())
            self.fillParticle(self.tree, 'l1_gen', event.the_hnl.l1())
            self.fillParticle(self.tree, 'l2_gen', event.the_hnl.l2())
            self.fillParticle(self.tree, 'n_gen', event.the_hnl.met())

        # reco primary vertex
        pv = event.goodVertices[0]
        self.fill(self.tree, 'pv_x', pv.x())
        self.fill(self.tree, 'pv_y', pv.y())
        self.fill(self.tree, 'pv_z', pv.z())
        self.fill(self.tree, 'pv_xe', pv.xError())
        self.fill(self.tree, 'pv_ye', pv.yError())
        self.fill(self.tree, 'pv_ze', pv.zError())

        # true primary vertex
        if hasattr(event, 'the_hnl'):
            self.fill(self.tree, 'pv_gen_x', event.the_hn.vx())
            self.fill(self.tree, 'pv_gen_y', event.the_hn.vy())
            self.fill(self.tree, 'pv_gen_z', event.the_hn.vz())

        # beamspot
        self.fill(self.tree, 'bs_x', event.beamspot.x0())
        self.fill(self.tree, 'bs_y', event.beamspot.y0())
        self.fill(self.tree, 'bs_z', event.beamspot.z0())
        self.fill(self.tree, 'bs_sigma_x', event.beamspot.BeamWidthX())
        self.fill(self.tree, 'bs_sigma_y', event.beamspot.BeamWidthY())
        self.fill(self.tree, 'bs_sigma_z', event.beamspot.sigmaZ())
        self.fill(self.tree, 'bs_dxdz', event.beamspot.dxdz())
        self.fill(self.tree, 'bs_dydz', event.beamspot.dydz())

        # true HN decay vertex
        if hasattr(event, 'the_hn'):
            self.fill(self.tree, 'sv_gen_x',
                      event.the_hn.lep1.vertex().x()
                      )  # don't use the final lepton to get the vertex from!
            self.fill(self.tree, 'sv_gen_y',
                      event.the_hn.lep1.vertex().y()
                      )  # don't use the final lepton to get the vertex from!
            self.fill(self.tree, 'sv_gen_z',
                      event.the_hn.lep1.vertex().z()
                      )  # don't use the final lepton to get the vertex from!

            # displacements
            self.fill(self.tree, 'hnl_2d_gen_disp',
                      displacement2D(event.the_hn.lep1, event.the_hn))
            self.fill(self.tree, 'hnl_3d_gen_disp',
                      displacement3D(event.the_hn.lep1, event.the_hn))

        # HLT bits & matches
        trig_list = [trig.name for trig in event.trigger_infos if trig.fired]
        if self.cfg_ana.promptLepType == 'ele':
            self.fill(
                self.tree, 'hlt_Ele27_WPTight_Gsf',
                any('HLT_Ele27_WPTight_Gsf' in name for name in trig_list))
            self.fill(
                self.tree, 'hlt_Ele32_WPTight_Gsf',
                any('HLT_Ele32_WPTight_Gsf' in name for name in trig_list))
            self.fill(
                self.tree, 'hlt_Ele35_WPTight_Gsf',
                any('HLT_Ele35_WPTight_Gsf' in name for name in trig_list))
            self.fill(
                self.tree, 'hlt_Ele115_CaloIdVT_GsfTrkIdT',
                any('HLT_Ele115_CaloIdVT_GsfTrkIdT' in name
                    for name in trig_list))
            self.fill(
                self.tree, 'hlt_Ele135_CaloIdVT_GsfTrkIdT',
                any('HLT_Ele135_CaloIdVT_GsfTrkIdT' in name
                    for name in trig_list))
        if self.cfg_ana.promptLepType == 'mu':
            self.fill(self.tree, 'hlt_soMu24',
                      any('HLT_IsoMu24' in name for name in trig_list))
            self.fill(self.tree, 'hlt_soMu27',
                      any('HLT_IsoMu27' in name for name in trig_list))
            self.fill(self.tree, 'hlt_u50',
                      any('HLT_Mu50' in name for name in trig_list))

        # reco secondary vertex and displacement
        self.fill(self.tree, 'sv_x', event.recoSv.x())
        self.fill(self.tree, 'sv_y', event.recoSv.y())
        self.fill(self.tree, 'sv_z', event.recoSv.z())
        self.fill(self.tree, 'sv_xe', event.recoSv.xError())
        self.fill(self.tree, 'sv_ye', event.recoSv.yError())
        self.fill(self.tree, 'sv_ze', event.recoSv.zError())
        self.fill(self.tree, 'sv_prob', event.recoSv.prob)
        self.fill(self.tree, 'sv_cos', event.recoSv.disp2DFromBS_cos)

        self.fill(self.tree, 'hnl_2d_disp',
                  event.recoSv.disp2DFromBS.value())  # from beamspot
        self.fill(self.tree, 'hnl_3d_disp',
                  event.recoSv.disp3DFromBS.value())  # from PV

        self.fill(self.tree, 'hnl_2d_disp_sig',
                  event.recoSv.disp2DFromBS_sig)  # from beamspot
        self.fill(self.tree, 'hnl_3d_disp_sig',
                  event.recoSv.disp3DFromBS_sig)  # from PV

        # jet/met variables
        self.fillExtraMetInfo(self.tree, event)

        #        set_trace()
        # met filter flags
        self.fill(self.tree, 'Flag_goodVertices', event.Flag_goodVertices)
        self.fill(self.tree, 'Flag_globalSuperTightHalo2016Filter',
                  event.Flag_globalSuperTightHalo2016Filter)
        self.fill(self.tree, 'Flag_HBHENoiseFilter',
                  event.Flag_HBHENoiseFilter)
        self.fill(self.tree, 'Flag_HBHENoiseIsoFilter',
                  event.Flag_HBHENoiseIsoFilter)
        self.fill(self.tree, 'Flag_EcalDeadCellTriggerPrimitiveFilter',
                  event.Flag_EcalDeadCellTriggerPrimitiveFilter)
        self.fill(self.tree, 'Flag_BadPFMuonFilter',
                  event.Flag_BadPFMuonFilter)
        self.fill(self.tree, 'Flag_BadChargedCandidateFilter',
                  event.Flag_BadChargedCandidateFilter)
        self.fill(self.tree, 'Flag_eeBadScFilter', event.Flag_eeBadScFilter)
        self.fill(self.tree, 'Flag_ecalBadCalibFilter',
                  event.Flag_ecalBadCalibFilter)
        #        self.fill(self.tree, 'Flag_any_met_filters', event.Flag_goodVertices or event.Flag_globalSuperTightHalo2016Filter or event.Flag_HBHENoiseFilter or event.Flag_HBHENoiseIsoFilter or event.Flag_EcalDeadCellTriggerPrimitiveFilter or event.Flag_BadPFMuonFilter or event.Flag_BadChargedCandidateFilter or event.Flag_eeBadScFilter or event.Flag_ecalBadCalibFilter)

        if len(event.cleanJets) > 0:
            self.fillJet(self.tree, 'j1', event.cleanJets[0], fill_extra=False)
        if len(event.cleanJets) > 1:
            self.fillJet(self.tree, 'j2', event.cleanJets[1], fill_extra=False)
        if len(event.cleanBJets) > 0:
            self.fillJet(self.tree,
                         'bj1',
                         event.cleanBJets[0],
                         fill_extra=False)
        if len(event.cleanBJets) > 1:
            self.fillJet(self.tree,
                         'bj2',
                         event.cleanBJets[1],
                         fill_extra=False)

        self.fill(self.tree, 'htj', event.HT_cleanJets)
        self.fill(self.tree, 'htbj', event.HT_bJets)
        self.fill(self.tree, 'nj', len(event.cleanJets))
        self.fill(self.tree, 'nbj', len(event.cleanBJets))

        # gen match
        if self.cfg_comp.isMC == True:
            stable_genp = [
                pp for pp in event.genParticles
                if ((pp.status() == 23 or pp.status() == 1) and (
                    pp.vertex().z() != 0))
            ]
            stable_genp += [
                pp for pp in event.genp_packed
                if ((pp.status() == 23 or pp.status() == 1) and (
                    pp.vertex().z() != 0))
            ]
            # particle status: http://home.thep.lu.se/~torbjorn/pythia81html/ParticleProperties.html
            # 1 ... stable; 23 ... from hardest scattering subprocess

            tomatch = [(event.the_3lep_cand.l0(), 0.05 * 0.05),
                       (event.the_3lep_cand.l1(), 0.2 * 0.2),
                       (event.the_3lep_cand.l2(), 0.2 * 0.2)]

            for ilep, idr2 in tomatch:
                bestmatch, dr2 = bestMatch(ilep, stable_genp)
                if (dr2 < idr2 and abs(
                    (ilep.pt() - bestmatch.pt()) / ilep.pt()) < 0.2):
                    ilep.bestmatch = bestmatch

            # relevant for signal: check if reco matched with gen, save a bool
            if hasattr(event.the_3lep_cand.l0(), 'bestmatch'):
                self.fillSimpleGenParticle(self.tree, 'l0_gen_match',
                                           event.the_3lep_cand.l0().bestmatch)
            if hasattr(event.the_3lep_cand.l1(), 'bestmatch'):
                self.fillSimpleGenParticle(self.tree, 'l1_gen_match',
                                           event.the_3lep_cand.l1().bestmatch)
            if hasattr(event.the_3lep_cand.l2(), 'bestmatch'):
                self.fillSimpleGenParticle(self.tree, 'l2_gen_match',
                                           event.the_3lep_cand.l2().bestmatch)

            # FIXME! matching by pointer does not work, so let's trick it with deltaR
            if hasattr(event, 'the_hnl'):
                if hasattr(event.the_3lep_cand.l0(), 'bestmatch'):
                    self.fill(
                        self.tree, 'l0_is_real',
                        deltaR(event.the_3lep_cand.l0().bestmatch,
                               event.the_hnl.l0()) < 0.01)
                if hasattr(event.the_3lep_cand.l1(), 'bestmatch'):
                    self.fill(
                        self.tree, 'l1_is_real',
                        deltaR(event.the_3lep_cand.l1().bestmatch,
                               event.the_hnl.l1()) < 0.05)
                if hasattr(event.the_3lep_cand.l2(), 'bestmatch'):
                    self.fill(
                        self.tree, 'l2_is_real',
                        deltaR(event.the_3lep_cand.l2().bestmatch,
                               event.the_hnl.l2()) < 0.05)

        # extra lepton veto
        self.fill(self.tree, 'pass_e_veto', len(event.veto_eles) == 0)
        self.fill(self.tree, 'pass_m_veto', len(event.veto_mus) == 0)

        # save vetoing lepton invariant masses
        if len(event.veto_eles):
            self.fillEle(self.tree, 'veto_ele', event.veto_save_ele)
            self.fill(self.tree, 'hnl_m_0Vele',
                      (event.veto_save_ele.p4() +
                       event.the_3lep_cand.l0().p4()).mass())
            self.fill(self.tree, 'hnl_m_1Vele',
                      (event.veto_save_ele.p4() +
                       event.the_3lep_cand.l1().p4()).mass())
            self.fill(self.tree, 'hnl_m_2Vele',
                      (event.veto_save_ele.p4() +
                       event.the_3lep_cand.l2().p4()).mass())
        if len(event.veto_mus):
            self.fillMuon(self.tree, 'veto_mu', event.veto_save_mu)
            self.fill(self.tree, 'hnl_m_0Vmu',
                      (event.veto_save_mu.p4() +
                       event.the_3lep_cand.l0().p4()).mass())
            self.fill(self.tree, 'hnl_m_1Vmu',
                      (event.veto_save_mu.p4() +
                       event.the_3lep_cand.l1().p4()).mass())
            self.fill(self.tree, 'hnl_m_2Vmu',
                      (event.veto_save_mu.p4() +
                       event.the_3lep_cand.l2().p4()).mass())
        # LHE weight
        self.fill(self.tree, 'lhe_weight',
                  np.sign(getattr(event, 'LHE_originalWeight', 1.)))

        self.fillTree(event)
Exemple #29
0
    def makeLeptons(self, event):
        ### inclusive leptons = all leptons that could be considered somewhere in the analysis, with minimal requirements (used e.g. to match to MC)
        event.inclusiveLeptons = []
        ### selected leptons = subset of inclusive leptons passing some basic id definition and pt requirement
        ### other    leptons = subset of inclusive leptons failing some basic id definition and pt requirement
        event.selectedLeptons = []
        event.selectedMuons = []
        event.selectedElectrons = []
        event.otherLeptons = []

        #muons
        allmuons = self.makeAllMuons(event)

        for mu in allmuons:
            # inclusive, very loose, selection
            if (mu.track().isNonnull() and mu.muonID(self.cfg_ana.inclusive_muon_id) and 
                    mu.pt()>self.cfg_ana.inclusive_muon_pt and abs(mu.eta())<self.cfg_ana.inclusive_muon_eta and 
                    abs(mu.dxy())<self.cfg_ana.inclusive_muon_dxy and abs(mu.dz())<self.cfg_ana.inclusive_muon_dz):
                event.inclusiveLeptons.append(mu)
                # basic selection
                if (mu.muonID(self.cfg_ana.loose_muon_id) and 
                        mu.pt() > self.cfg_ana.loose_muon_pt and abs(mu.eta()) < self.cfg_ana.loose_muon_eta and 
                        abs(mu.dxy()) < self.cfg_ana.loose_muon_dxy and abs(mu.dz()) < self.cfg_ana.loose_muon_dz and
                        mu.relIso03 < self.cfg_ana.loose_muon_relIso and 
                        mu.absIso03 < (self.cfg_ana.loose_muon_absIso if hasattr(self.cfg_ana,'loose_muon_absIso') else 9e99)):
                    mu.looseIdSusy = True
                    event.selectedLeptons.append(mu)
                    event.selectedMuons.append(mu)
                else:
                    mu.looseIdSusy = False
                    event.otherLeptons.append(mu)

        #electrons        
        allelectrons = self.makeAllElectrons(event)

        looseMuons = event.selectedLeptons[:]
        for ele in allelectrons:
            ## remove muons if muForEleCrossCleaning is not empty
            ## apply selection
            if ( ele.electronID(self.cfg_ana.inclusive_electron_id) and
                    ele.pt()>self.cfg_ana.inclusive_electron_pt and abs(ele.eta())<self.cfg_ana.inclusive_electron_eta and 
                    abs(ele.dxy())<self.cfg_ana.inclusive_electron_dxy and abs(ele.dz())<self.cfg_ana.inclusive_electron_dz and 
                    ele.lostInner()<=self.cfg_ana.inclusive_electron_lostHits ):
                event.inclusiveLeptons.append(ele)
                # basic selection
                if (ele.electronID(self.cfg_ana.loose_electron_id) and
                         ele.pt()>self.cfg_ana.loose_electron_pt and abs(ele.eta())<self.cfg_ana.loose_electron_eta and 
                         abs(ele.dxy()) < self.cfg_ana.loose_electron_dxy and abs(ele.dz())<self.cfg_ana.loose_electron_dz and 
                         ele.relIso03 <= self.cfg_ana.loose_electron_relIso and
                         ele.absIso03 < (self.cfg_ana.loose_electron_absIso if hasattr(self.cfg_ana,'loose_electron_absIso') else 9e99) and
                         ele.lostInner() <= self.cfg_ana.loose_electron_lostHits and
                         ( True if (hasattr(self.cfg_ana,'notCleaningElectrons') and self.cfg_ana.notCleaningElectrons) else (bestMatch(ele, looseMuons)[1] > (self.cfg_ana.min_dr_electron_muon**2)) )):
                    event.selectedLeptons.append(ele)
                    event.selectedElectrons.append(ele)
                    ele.looseIdSusy = True
                else:
                    event.otherLeptons.append(ele)
                    ele.looseIdSusy = False

        event.otherLeptons.sort(key = lambda l : l.pt(), reverse = True)
        event.selectedLeptons.sort(key = lambda l : l.pt(), reverse = True)
        event.selectedMuons.sort(key = lambda l : l.pt(), reverse = True)
        event.selectedElectrons.sort(key = lambda l : l.pt(), reverse = True)
        event.inclusiveLeptons.sort(key = lambda l : l.pt(), reverse = True)

        for lepton in event.selectedLeptons:
            if hasattr(self,'efficiency'):
                self.efficiency.attachToObject(lepton)
Exemple #30
0
                    abs(jet.eta()) < 3.0 and
                    jet.pt() < 200.5)
            ]
            jets = removeOverlap(all_jets, genLeptons)

            event.getByLabel("slimmedGenJets", genJetH)
            all_gen_jets = [
                jet for jet in genJetH.product()
                if (jet.pt() > 20 and
                    abs(jet.eta()) < 3.0 and
                    jet.pt() < 200.5)
            ]
            gen_jets = removeOverlap(all_gen_jets, genLeptons)
            matched_jets = []
            for jet in jets:
                genjet, dr2 = bestMatch(jet, gen_jets)
                if dr2 < 0.01:
                    matched_jets.append(jet)
            refObjs = copy.deepcopy(matched_jets)
        elif runtype in ele_run_types:
            refObjs = copy.deepcopy(genElectrons)
        elif runtype in muon_run_types:
            refObjs = copy.deepcopy(genMuons)

        ###
        Matched = MatchTausToJets(refObjs)

        ###
        h_ngen.Fill(len(refObjs))
        for refidx,refObj in enumerate(refObjs):
            for var in all_vars:
Exemple #31
0
    def process(self, event, fill=True):
        '''
        '''
        self.readCollections(event.input)
        self.tree.reset()

        self.counters.counter('HNLTreeProducer').inc('all events')

        # save the event only if it is in the correct final state
        if not eval(self.finalStateFilter):
            return True
        self.counters.counter('HNLTreeProducer').inc('pass final state')

        # get ahold of the objects to save
        final_state = self.cfg_ana.promptLepType + self.cfg_ana.L1L2LeptonType
        dileptonsvtx = event.dileptonsvtx_dict[final_state]
        the_3lep_cand = event.the_3lep_cand_dict[final_state]
        recoSv = event.recoSv_dict[final_state]

        # save the event only if it passes the skim selection (if it exists)
        # import pdb ; pdb.set_trace()
        if not eval(self.skimFilter):
            return True

        self.counters.counter('HNLTreeProducer').inc('pass skim')

        # also cleaned jet collections depend on the final state
        cleanJets = event.cleanJets[final_state]
        cleanBJets = event.cleanBJets[final_state]
        cleanJets30 = event.cleanJets30[final_state]

        # adjust the weights, according to the final state
        event.eventWeight = getattr(event, 'puWeight', 1.)  * \
                            getattr(event, 'LHE_originalWeight', 1.)  * \
                            getattr(event, 'weight_%s' %final_state, 1.)

        the_3lep_cand.l0().weight = getattr(the_3lep_cand.l0(),
                                            'weight_%s' % final_state, 1.)
        the_3lep_cand.l0().weight_id = getattr(the_3lep_cand.l0(),
                                               'weight_%s_id' % final_state,
                                               1.)
        the_3lep_cand.l0().weight_iso = getattr(the_3lep_cand.l0(),
                                                'weight_%s_iso' % final_state,
                                                1.)
        the_3lep_cand.l0().weight_reco = getattr(
            the_3lep_cand.l0(), 'weight_%s_reco' % final_state, 1.)
        the_3lep_cand.l0().weight_idiso = getattr(
            the_3lep_cand.l0(), 'weight_%s_idiso' % final_state, 1.)
        the_3lep_cand.l0().weight_trigger = getattr(
            the_3lep_cand.l0(), 'weight_%s_trigger' % final_state, 1.)
        the_3lep_cand.l0().weight_tracking = getattr(
            the_3lep_cand.l0(), 'weight_%s_tracking' % final_state, 1.)

        the_3lep_cand.l1().weight = getattr(the_3lep_cand.l1(),
                                            'weight_%s' % final_state, 1.)
        the_3lep_cand.l1().weight_id = getattr(the_3lep_cand.l1(),
                                               'weight_%s_id' % final_state,
                                               1.)
        the_3lep_cand.l1().weight_iso = getattr(the_3lep_cand.l1(),
                                                'weight_%s_iso' % final_state,
                                                1.)
        the_3lep_cand.l1().weight_reco = getattr(
            the_3lep_cand.l1(), 'weight_%s_reco' % final_state, 1.)
        the_3lep_cand.l1().weight_idiso = getattr(
            the_3lep_cand.l1(), 'weight_%s_idiso' % final_state, 1.)
        the_3lep_cand.l1().weight_trigger = getattr(
            the_3lep_cand.l1(), 'weight_%s_trigger' % final_state, 1.)
        the_3lep_cand.l1().weight_tracking = getattr(
            the_3lep_cand.l1(), 'weight_%s_tracking' % final_state, 1.)

        the_3lep_cand.l2().weight = getattr(the_3lep_cand.l2(),
                                            'weight_%s' % final_state, 1.)
        the_3lep_cand.l2().weight_id = getattr(the_3lep_cand.l2(),
                                               'weight_%s_id' % final_state,
                                               1.)
        the_3lep_cand.l2().weight_iso = getattr(the_3lep_cand.l2(),
                                                'weight_%s_iso' % final_state,
                                                1.)
        the_3lep_cand.l2().weight_reco = getattr(
            the_3lep_cand.l2(), 'weight_%s_reco' % final_state, 1.)
        the_3lep_cand.l2().weight_idiso = getattr(
            the_3lep_cand.l2(), 'weight_%s_idiso' % final_state, 1.)
        the_3lep_cand.l2().weight_trigger = getattr(
            the_3lep_cand.l2(), 'weight_%s_trigger' % final_state, 1.)
        the_3lep_cand.l2().weight_tracking = getattr(
            the_3lep_cand.l2(), 'weight_%s_tracking' % final_state, 1.)

        # event variables
        self.fillEvent(self.tree, event)
        self.fill(self.tree, 'n_cands', len(dileptonsvtx))
        # these are PRESELECTED leptons according to the preselection given via cfg

        # reco HNL
        self.fillHNL(self.tree, 'hnl', the_3lep_cand)
        if self.cfg_ana.L1L2LeptonType == 'mm':
            self.fillMuon(self.tree, 'l1', the_3lep_cand.l1())
            self.fillMuon(self.tree, 'l2', the_3lep_cand.l2())
        if self.cfg_ana.L1L2LeptonType == 'ee':
            self.fillEle(self.tree, 'l1', the_3lep_cand.l1())
            self.fillEle(self.tree, 'l2', the_3lep_cand.l2())
        if self.cfg_ana.L1L2LeptonType == 'em':
            self.fillEle(self.tree, 'l1', the_3lep_cand.l1())
            self.fillMuon(self.tree, 'l2', the_3lep_cand.l2())

        if self.cfg_ana.promptLepType == 'e':
            self.fillEle(self.tree, 'l0', the_3lep_cand.l0())
        if self.cfg_ana.promptLepType == 'm':
            self.fillMuon(self.tree, 'l0', the_3lep_cand.l0())

        # output of MC analysis ONLY FOR SIGNAL
        if hasattr(event, 'the_hnl'):
            self.fillHNL(self.tree, 'hnl_gen', event.the_hnl)
            self.fillParticle(self.tree, 'l0_gen', event.the_hnl.l0())
            self.fillParticle(self.tree, 'l1_gen', event.the_hnl.l1())
            self.fillParticle(self.tree, 'l2_gen', event.the_hnl.l2())
            self.fillParticle(self.tree, 'n_gen', event.the_hnl.met())

        # reco primary vertex
        pv = event.goodVertices[0]
        self.fill(self.tree, 'pv_x', pv.x())
        self.fill(self.tree, 'pv_y', pv.y())
        self.fill(self.tree, 'pv_z', pv.z())
        self.fill(self.tree, 'pv_xe', pv.xError())
        self.fill(self.tree, 'pv_ye', pv.yError())
        self.fill(self.tree, 'pv_ze', pv.zError())

        # true primary vertex
        if hasattr(event, 'the_hnl'):
            self.fill(self.tree, 'pv_gen_x', event.the_hn.vx())
            self.fill(self.tree, 'pv_gen_y', event.the_hn.vy())
            self.fill(self.tree, 'pv_gen_z', event.the_hn.vz())

        # beamspot
        self.fill(self.tree, 'bs_x', event.beamspot.x0())
        self.fill(self.tree, 'bs_y', event.beamspot.y0())
        self.fill(self.tree, 'bs_z', event.beamspot.z0())
        self.fill(self.tree, 'bs_sigma_x', event.beamspot.BeamWidthX())
        self.fill(self.tree, 'bs_sigma_y', event.beamspot.BeamWidthY())
        self.fill(self.tree, 'bs_sigma_z', event.beamspot.sigmaZ())
        self.fill(self.tree, 'bs_dxdz', event.beamspot.dxdz())
        self.fill(self.tree, 'bs_dydz', event.beamspot.dydz())

        # true HN decay vertex
        if hasattr(event, 'the_hn'):
            self.fill(self.tree, 'sv_gen_x',
                      event.the_hn.lep1.vertex().x()
                      )  # don't use the final lepton to get the vertex from!
            self.fill(self.tree, 'sv_gen_y',
                      event.the_hn.lep1.vertex().y()
                      )  # don't use the final lepton to get the vertex from!
            self.fill(self.tree, 'sv_gen_z',
                      event.the_hn.lep1.vertex().z()
                      )  # don't use the final lepton to get the vertex from!

            # displacements
            self.fill(self.tree, 'hnl_2d_gen_disp',
                      displacement2D(event.the_hn.lep1, event.the_hn))
            self.fill(self.tree, 'hnl_3d_gen_disp',
                      displacement3D(event.the_hn.lep1, event.the_hn))

        # HLT bits & matches
        trig_list = [trig.name for trig in event.trigger_infos if trig.fired]
        if self.cfg_ana.promptLepType == 'e':
            self.fill(
                self.tree, 'hlt_Ele25_eta2p1_WPTight_Gsf',
                any('HLT_Ele25_eta2p1_WPTight_Gsf' in name
                    for name in trig_list))
            self.fill(
                self.tree, 'hlt_Ele27_WPTight_Gsf',
                any('HLT_Ele27_WPTight_Gsf' in name for name in trig_list))
            self.fill(
                self.tree, 'hlt_Ele32_WPTight_Gsf',
                any('HLT_Ele32_WPTight_Gsf' in name for name in trig_list))
            self.fill(
                self.tree, 'hlt_Ele35_WPTight_Gsf',
                any('HLT_Ele35_WPTight_Gsf' in name for name in trig_list))
            self.fill(
                self.tree, 'hlt_Ele115_CaloIdVT_GsfTrkIdT',
                any('HLT_Ele115_CaloIdVT_GsfTrkIdT' in name
                    for name in trig_list))
            self.fill(
                self.tree, 'hlt_Ele135_CaloIdVT_GsfTrkIdT',
                any('HLT_Ele135_CaloIdVT_GsfTrkIdT' in name
                    for name in trig_list))
        if self.cfg_ana.promptLepType == 'm':
            self.fill(self.tree, 'hlt_IsoMu22',
                      any('HLT_IsoMu22' in name for name in trig_list))
            self.fill(self.tree, 'hlt_IsoTkMu22',
                      any('HLT_IsoTkMu22' in name for name in trig_list))
            self.fill(self.tree, 'hlt_IsoMu22_eta2p1',
                      any('HLT_IsoMu22_eta2p1' in name for name in trig_list))
            self.fill(
                self.tree, 'hlt_IsoTkMu22_eta2p1',
                any('HLT_IsoTkMu22_eta2p1' in name for name in trig_list))
            self.fill(self.tree, 'hlt_IsoMu24',
                      any('HLT_IsoMu24' in name for name in trig_list))
            self.fill(self.tree, 'hlt_IsoTkMu24',
                      any('HLT_IsoTkMu24' in name for name in trig_list))
            self.fill(self.tree, 'hlt_IsoMu27',
                      any('HLT_IsoMu27' in name for name in trig_list))
            self.fill(self.tree, 'hlt_IsoTkMu27',
                      any('HLT_IsoTkMu27' in name for name in trig_list))
            self.fill(self.tree, 'hlt_Mu50',
                      any('HLT_Mu50' in name for name in trig_list))
            self.fill(self.tree, 'hlt_TkMu50',
                      any('HLT_TkMu50' in name for name in trig_list))

        # reco secondary vertex and displacement
        self.fillVertex(self.tree, 'sv', recoSv)

        self.fill(self.tree, 'hnl_2d_disp',
                  recoSv.disp2DFromBS.value())  # from beamspot
        self.fill(self.tree, 'hnl_3d_disp',
                  recoSv.disp3DFromBS.value())  # from PV

        self.fill(self.tree, 'hnl_2d_disp_sig',
                  recoSv.disp2DFromBS_sig)  # from beamspot
        self.fill(self.tree, 'hnl_3d_disp_sig',
                  recoSv.disp3DFromBS_sig)  # from PV

        # jet/met variables
        self.fillExtraMetInfo(self.tree, event)

        # met filter flags
        self.fill(self.tree, 'pass_met_filters', event.pass_met_filters)

        if len(cleanJets) > 0:
            self.fillJet(self.tree, 'j1', cleanJets[0], fill_extra=False)
        if len(cleanJets) > 1:
            self.fillJet(self.tree, 'j2', cleanJets[1], fill_extra=False)
        if len(cleanBJets) > 0:
            self.fillJet(self.tree, 'bj1', cleanBJets[0], fill_extra=False)
        if len(cleanBJets) > 1:
            self.fillJet(self.tree, 'bj2', cleanBJets[1], fill_extra=False)

        self.fill(self.tree, 'nj', len(cleanJets))
        self.fill(self.tree, 'nj30', len(cleanJets30))
        self.fill(self.tree, 'nbj', len(cleanBJets))

        # FIXME! RM what is this?
        # gen match
        if self.cfg_comp.isMC == True and hasattr(event, 'genParticles'):
            stable_genp = [
                pp for pp in event.genParticles if pp.status() == 1
            ]  # and pp.vertex().z()!=0)]
            stable_genp += [
                pp for pp in event.genp_packed if pp.status() == 1
            ]  # and pp.vertex().z()!=0)]
            # particle status: http://home.thep.lu.se/~torbjorn/pythia81html/ParticleProperties.html
            # 1 ... stable; 23 ... from hardest scattering subprocess
            #            stable_genp += [pp for pp in event.genParticles if (pp.status()==23  and pp.vertex().z()!=0)]
            #            stable_genp += [pp for pp in event.genp_packed  if (pp.status()==23  and pp.vertex().z()!=0)]

            tomatch = [(the_3lep_cand.l0(), 0.05 * 0.05),
                       (the_3lep_cand.l1(), 0.2 * 0.2),
                       (the_3lep_cand.l2(), 0.2 * 0.2)]

            for ilep, idr2 in tomatch:
                bestmatch, dr2 = bestMatch(ilep, stable_genp)
                if (dr2 < idr2 and abs(
                    (ilep.pt() - bestmatch.pt()) / ilep.pt()) < 0.2):
                    ilep.bestmatch = bestmatch

            # relevant for mc: check if reco matched with gen, save a float
            if hasattr(the_3lep_cand.l0(), 'bestmatch'):
                LEP0 = the_3lep_cand.l0()
                self.fillSimpleGenParticle(self.tree, 'l0_gen_match',
                                           LEP0.bestmatch)
                self.fill(self.tree, 'l0_good_match',
                          deltaR(LEP0.bestmatch, LEP0))
#                if deltaR(LEP0.bestmatch, LEP0) < 0.04 and LEP0.pdgId() == LEP0.bestmatch.pdgId():
#                    self.fill(self.tree, 'l0_good_match', 1)

            if hasattr(the_3lep_cand.l1(), 'bestmatch'):
                LEP1 = the_3lep_cand.l1()
                self.fillSimpleGenParticle(self.tree, 'l1_gen_match',
                                           LEP1.bestmatch)
                self.fill(self.tree, 'l1_good_match',
                          deltaR(LEP1.bestmatch, LEP1))
#                if deltaR(LEP1.bestmatch, LEP1) < 0.04 and LEP1.pdgId() == LEP1.bestmatch.pdgId():
#                    self.fill(self.tree, 'l1_good_match', 1)

            if hasattr(the_3lep_cand.l2(), 'bestmatch'):
                LEP2 = the_3lep_cand.l2()
                self.fillSimpleGenParticle(self.tree, 'l2_gen_match',
                                           LEP2.bestmatch)
                self.fill(self.tree, 'l2_good_match',
                          deltaR(LEP2.bestmatch, LEP2))
#                if deltaR(LEP2.bestmatch, LEP2) < 0.04 and LEP2.pdgId() == LEP2.bestmatch.pdgId():
#                    self.fill(self.tree, 'l2_good_match', 1)

# matching by pointer does not work, so let's trick it with deltaR
            if hasattr(event, 'the_hnl'):
                if hasattr(the_3lep_cand.l0(), 'bestmatch'):
                    self.fill(
                        self.tree, 'l0_is_real',
                        deltaR(the_3lep_cand.l0().bestmatch,
                               event.the_hnl.l0()) < 0.01)
                if hasattr(the_3lep_cand.l1(), 'bestmatch'):
                    self.fill(
                        self.tree, 'l1_is_real',
                        deltaR(the_3lep_cand.l1().bestmatch,
                               event.the_hnl.l1()) < 0.05)
                if hasattr(the_3lep_cand.l2(), 'bestmatch'):
                    self.fill(
                        self.tree, 'l2_is_real',
                        deltaR(the_3lep_cand.l2().bestmatch,
                               event.the_hnl.l2()) < 0.05)

            # print('event:', event.eventId, 'lumi:', event.lumi)

        # extra lepton veto
        self.fill(self.tree, 'pass_e_veto', len(event.veto_eles) == 0)
        self.fill(self.tree, 'pass_m_veto', len(event.veto_mus) == 0)

        # LHE weight
        self.fill(self.tree, 'lhe_weight',
                  np.sign(getattr(event, 'LHE_originalWeight', 1.)))

        # weights for ctau reweighing (only for signal!)
        if 'HN3L' in self.cfg_comp.name:
            for iv2 in new_v2s:
                # 'stringify' the coupling
                # reduce precision to avoid nasty numbers e.g. 6.000000000000001e-05
                iv2_name = np.format_float_scientific(iv2,
                                                      unique=False,
                                                      precision=1,
                                                      exp_digits=2)
                iv2_name = iv2_name.replace('-', 'm')
                self.fill(self.tree, 'ctau_w_v2_%s' % iv2_name,
                          event.ctau_weights[iv2]['ctau_weight'])
                self.fill(self.tree, 'xs_w_v2_%s' % iv2_name,
                          event.ctau_weights[iv2]['xs_weight'])
            if event.the_gen_w is not None:
                self.fillParticle(self.tree, 'w_gen', event.the_gen_w)

        self.fill(self.tree, 'pass_mmm', getattr(event, 'pass_mmm', -1.))
        self.fill(self.tree, 'pass_mem', getattr(event, 'pass_mem', -1.))
        self.fill(self.tree, 'pass_eee', getattr(event, 'pass_eee', -1.))
        self.fill(self.tree, 'pass_eem', getattr(event, 'pass_eem', -1.))

        #         import pdb ; pdb.set_trace()

        if fill:
            self.fillTree(event)
Exemple #32
0
    def process(self, event):
        
        self.tree.reset()

        ntuple.fillEvent(self.tree, event)
                
        ntuple.fillParticle(self.tree, 'b', event.theb)
        ntuple.fillParticle(self.tree, 'jpsi', event.theb.jpsi())
        ntuple.fillMuon(self.tree, 'mu1'   , event.theb.l0())
        ntuple.fillParticle(self.tree, 'tk2'   , event.theb.l1())
        mu2, dR2 = bestMatch(event.theb.l1(), event.muons)
        if dR2<0.005*0.005 and mu2.physObj != event.theb.l0().physObj:
            ntuple.fillMuon(self.tree, 'mu2', mu2)

        ntuple.fillParticle(self.tree, 'k', event.theb.k())

        ntuple.fill(self.tree, 'dr_mm'        , deltaR(event.theb.l0()    , event.theb.l1()))
        ntuple.fill(self.tree, 'dr_jpsi_k'    , deltaR(event.theb.jpsi()  , event.theb.k() ))
        ntuple.fill(self.tree, 'dr_jpsi_mu1'  , deltaR(event.theb.jpsi()  , event.theb.l0()))
        ntuple.fill(self.tree, 'dr_jpsi_mu2'  , deltaR(event.theb.jpsi()  , event.theb.l1()))
        ntuple.fill(self.tree, 'dr_mu1_k'     , deltaR(event.theb.l0()    , event.theb.k() ))
        ntuple.fill(self.tree, 'dr_mu2_k'     , deltaR(event.theb.l1()    , event.theb.k() ))

        ntuple.fill(self.tree, 'dphi_mm'      , deltaPhi(event.theb.l0()  .phi(), event.theb.l1().phi()))
        ntuple.fill(self.tree, 'dphi_jpsi_k'  , deltaPhi(event.theb.jpsi().phi(), event.theb.k() .phi()))
        ntuple.fill(self.tree, 'dphi_jpsi_mu1', deltaPhi(event.theb.jpsi().phi(), event.theb.l0().phi()))
        ntuple.fill(self.tree, 'dphi_jpsi_mu2', deltaPhi(event.theb.jpsi().phi(), event.theb.l1().phi()))
        ntuple.fill(self.tree, 'dphi_mu1_k'   , deltaPhi(event.theb.l0()  .phi(), event.theb.k() .phi()))
        ntuple.fill(self.tree, 'dphi_mu2_k'   , deltaPhi(event.theb.l1()  .phi(), event.theb.k() .phi()))

        ntuple.fill(self.tree, 'b_cone'       , event.theb.bcone())

        ntuple.fill(self.tree, 'bs_x', event.beamspot.x0())
        ntuple.fill(self.tree, 'bs_y', event.beamspot.y0())
        ntuple.fill(self.tree, 'bs_z', event.beamspot.z0())

        ntuple.fill(self.tree, 'pv_x', event.pv.x())
        ntuple.fill(self.tree, 'pv_y', event.pv.y())
        ntuple.fill(self.tree, 'pv_z', event.pv.z())

        if event.theb.vtx().isValid():
            ntuple.fill(self.tree, 'sv_x', event.theb.vtx().position().x())
            ntuple.fill(self.tree, 'sv_y', event.theb.vtx().position().y())
            ntuple.fill(self.tree, 'sv_z', event.theb.vtx().position().z())

            ntuple.fill(self.tree, 'sv_chi2', event.theb.vtx().normalisedChiSquared())
            ntuple.fill(self.tree, 'sv_prob', ROOT.TMath.Prob(event.theb.vtx().normalisedChiSquared(), 1))

            ntuple.fill(self.tree, 'sv_2d_disp'      , event.theb.disp2d().value())
            ntuple.fill(self.tree, 'sv_2d_disp_err'  , event.theb.disp2d().error())
            ntuple.fill(self.tree, 'sv_2d_disp_sig'  , event.theb.ls2d())
            ntuple.fill(self.tree, 'sv_2d_cos'       , event.theb.vtxcos())

        for info, hlt in product(event.trigger_infos, ['HLT_Mu7p5_Track2_Jpsi', 'HLT_Mu7p5_Track3p5_Jpsi', 'HLT_Mu7p5_Track7_Jpsi']):
            if hlt in info.name:
                ntuple.fill(self.tree, hlt, info.fired)
                ntuple.fill(self.tree, hlt+'_ps', info.prescale)

#         ntuple.fill(self.tree, 'HLT_Mu7p5_Track2_Jpsi_v9'  , any([True for info in event.trigger_infos if info.name == 'HLT_Mu7p5_Track2_Jpsi_v9'   and info.fired]))
#         ntuple.fill(self.tree, 'HLT_Mu7p5_Track3p5_Jpsi_v9', any([True for info in event.trigger_infos if info.name == 'HLT_Mu7p5_Track3p5_Jpsi_v9' and info.fired]))
#         ntuple.fill(self.tree, 'HLT_Mu7p5_Track7_Jpsi_v9'  , any([True for info in event.trigger_infos if info.name == 'HLT_Mu7p5_Track7_Jpsi_v9'   and info.fired]))
# 
#         ntuple.fill(self.tree, 'HLT_Mu7p5_Track2_Jpsi_v9_ps'  , any([True for info in event.trigger_infos if info.name == 'HLT_Mu7p5_Track2_Jpsi_v9'   and info.fired]))
#         ntuple.fill(self.tree, 'HLT_Mu7p5_Track3p5_Jpsi_v9_ps', any([True for info in event.trigger_infos if info.name == 'HLT_Mu7p5_Track3p5_Jpsi_v9' and info.fired]))
#         ntuple.fill(self.tree, 'HLT_Mu7p5_Track7_Jpsi_v9_ps'  , any([True for info in event.trigger_infos if info.name == 'HLT_Mu7p5_Track7_Jpsi_v9'   and info.fired]))

        
        self.tree.tree.Fill()
Exemple #33
0
                charged_p4 = sum(
                    (d.p4() for d in refObj.final_ds if d.charge()),
                    ROOT.math.XYZTLorentzVectorD())
                neutral_p4 = sum(
                    (d.p4() for d in refObj.final_ds
                     if abs(d.pdgId()) not in [12, 14, 16] and not d.charge()),
                    ROOT.math.XYZTLorentzVectorD())
                all_var_dict['gen_charged_pt'].fill(charged_p4.pt())
                all_var_dict['gen_neutral_pt'].fill(neutral_p4.pt())
            else:
                all_var_dict['gen_dm'].fill(-1)
                all_var_dict['gen_pt'].fill(refObj.pt())
                all_var_dict['gen_eta'].fill(refObj.eta())
                all_var_dict['gen_phi'].fill(refObj.phi())

            electron, dr = bestMatch(refObj, electrons)
            if dr < 0.5:
                # Fill reco-tau variables if it exists...
                NMatchedTaus += 1

                all_var_dict['electron_pt'].fill(electron.pt())
                all_var_dict['electron_eta'].fill(electron.eta())
                all_var_dict['electron_phi'].fill(electron.phi())
                e_p = electron.trackMomentumAtVtx().R()
                e_sc = electron.eSuperClusterOverP() * e_p
                e_sc_o_p = 2 * e_sc / (e_p + e_sc)
                all_var_dict['electron_eSuperClusterOverP_norm'].fill(e_sc_o_p)

                e_seed = electron.eSeedClusterOverP() * e_p

                hcal = electron.hcalOverEcal() * e_seed
Exemple #34
0
    def process(self, event):
        self.readCollections(event.input)
        self.counters.counter('RecoGenTreeAnalyzer').inc('all events')

        # produce collections and map our objects to convenient Heppy objects
        event.muons = map(Muon, self.handles['muons'].product())
        event.electrons = map(Electron, self.handles['electrons'].product())
        event.photons = map(Photon, self.handles['photons'].product())
        event.taus = map(Tau, self.handles['taus'].product())
        event.jets = map(Jet, self.handles['jets'].product())
        event.dsmuons = self.buildDisplacedMuons(
            self.handles['dsmuons'].product())
        event.dgmuons = self.buildDisplacedMuons(
            self.handles['dgmuons'].product())

        # vertex stuff
        event.pvs = self.handles['pvs'].product()
        event.svs = self.handles['svs'].product()
        event.beamspot = self.handles['beamspot'].product()

        # met
        event.met = self.handles['met'].product().at(0)

        # assign to the leptons the primary vertex, will be needed to compute a few quantities
        # FIXME! understand exactly to which extent it is reasonable to assign the PV to *all* leptons
        #        regardless whether they're displaced or not
        if len(event.pvs):
            myvtx = event.pvs[0]
        else:
            myvtx = event.beamspot

        self.assignVtx(event.muons, myvtx)
        self.assignVtx(event.electrons, myvtx)
        self.assignVtx(event.photons, myvtx)
        self.assignVtx(event.taus, myvtx)

        # all matchable objects
        # matchable = event.electrons + event.photons + event.muons + event.taus + event.dsmuons + event.dgmuons
        matchable = event.electrons + event.photons + event.muons + event.taus + event.dsmuons

        # match gen to reco
        for ip in [event.the_hnl.l0(), event.the_hnl.l1(), event.the_hnl.l2()]:
            ip.bestmatch = None
            ip.bestmatchtype = None
            ip.matches = inConeCollection(ip, matchable,
                                          getattr(self.cfg_ana, 'drmax', 0.2),
                                          0.)

            # matches the corresponding "slimmed electron" to the gen particle
            if len(event.electrons):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.electrons)
                if dr2 < 0.04:
                    ip.bestelectron = match

            # matches the corresponding "slimmed photon" to the gen particle
            if len(event.photons):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.photons)
                if dr2 < 0.04:
                    ip.bestphoton = match

            # matches the corresponding "slimmed muon" to the gen particle
            if len(event.muons):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.muons)
                if dr2 < 0.04:
                    ip.bestmuon = match

            # matches the corresponding "slimmed tau" to the gen particle
            if len(event.taus):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.taus)
                if dr2 < 0.04:
                    ip.besttau = match

            # matches the corresponding "displaced stand alone muon" to the gen particle
            if len(event.dsmuons):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.dsmuons)
                if dr2 < 0.04:
                    ip.bestdsmuon = match

            # matches the corresponding "displaced global muon" to the gen particle
            if len(event.dgmuons):
                dr2 = np.inf
                match, dr2 = bestMatch(ip, event.dgmuons)
                if dr2 < 0.04:
                    ip.bestdgmuon = match

            # to find the best match, give precedence to any matched
            # particle in the matching cone with the correct PDG ID
            # then to the one which is closest
            ip.matches.sort(key=lambda x:
                            (x.pdgId() == ip.pdgId(), -deltaR(x, ip)),
                            reverse=True)
            if len(ip.matches) and abs(ip.pdgId()) == abs(
                    ip.matches[0].pdgId()):
                ip.bestmatch = ip.matches[0]
                # remove already matched particles, avoid multiple matches to the same candidate while recording the type of reconstruction
                matchable.remove(ip.bestmatch)

                # record which is which
                if ip.bestmatch in event.electrons: ip.bestmatchtype = 11
                if ip.bestmatch in event.photons: ip.bestmatchtype = 22
                if ip.bestmatch in event.muons: ip.bestmatchtype = 13
                if ip.bestmatch in event.taus: ip.bestmatchtype = 15
                if ip.bestmatch in event.dsmuons: ip.bestmatchtype = 26
                if ip.bestmatch in event.dgmuons: ip.bestmatchtype = 39

            else:
                ip.bestmatchtype = -1

        # clear it before doing it again
        event.recoSv = None

        # if hasattr(event.the_hnl.l2().bestmatch, 'pt'):
        # set_trace()
        # if (abs(event.the_hnl.l1().pt()-13.851562)<0.001):
        # set_trace()

        ######### DEBUG VTX MADE OUT OF DSA MUONS
        #         if len(event.dsmuons) > 2:
        #             # clear the vector
        #             self.tofit.clear()
        #             # create a RecoChargedCandidate for each reconstructed lepton and flush it into the vector
        #             for il in [event.dsmuons[0], event.dsmuons[1]]:
        #                 # if the reco particle is a displaced thing, it does not have the p4() method, so let's build it
        #                 myp4 = ROOT.Math.LorentzVector('<ROOT::Math::PxPyPzE4D<double> >')(il.px(), il.py(), il.pz(), math.sqrt(il.mass()**2 + il.px()**2 + il.py()**2 + il.pz()**2))
        #                 ic = ROOT.reco.RecoChargedCandidate() # instantiate a dummy RecoChargedCandidate
        #                 ic.setCharge(il.charge())             # assign the correct charge
        #                 ic.setP4(myp4)                        # assign the correct p4
        #                 ic.setTrack(il.track())               # set the correct TrackRef
        #                 if ic.track().isNonnull():            # check that the track is valid, there are photons around too!
        #                     self.tofit.push_back(ic)
        #             # further sanity check: two *distinct* tracks
        #             if self.tofit.size()==2 and self.tofit[0].track() != self.tofit[1].track():
        #                 # fit it!
        #                 svtree = self.vtxfit.Fit(self.tofit) # actual vertex fitting
        #                 # check that the vertex is good
        #                 if not svtree.get().isEmpty() and svtree.get().isValid():
        #                     svtree.movePointerToTheTop()
        #                     sv = svtree.currentDecayVertex().get()
        #                     event.recoSv = makeRecoVertex(sv, kinVtxTrkSize=2) # need to do some gymastics
        #                     print 'good double dsa vertex! vx=%.2f, vy=%.2f, vz=%.2f' %(event.recoSv.x(), event.recoSv.y(), event.recoSv.z())
        #                     import pdb ; pdb.set_trace()

        # let's refit the secondary vertex, IF both leptons match to some reco particle
        if not(event.the_hnl.l1().bestmatch is None or \
               event.the_hnl.l2().bestmatch is None):
            # clear the vector
            self.tofit.clear()
            # create a RecoChargedCandidate for each reconstructed lepton and flush it into the vector
            for il in [
                    event.the_hnl.l1().bestmatch,
                    event.the_hnl.l2().bestmatch
            ]:
                # if the reco particle is a displaced thing, it does not have the p4() method, so let's build it
                myp4 = ROOT.Math.LorentzVector(
                    '<ROOT::Math::PxPyPzE4D<double> >')(
                        il.px(), il.py(), il.pz(),
                        math.sqrt(il.mass()**2 + il.px()**2 + il.py()**2 +
                                  il.pz()**2))
                ic = ROOT.reco.RecoChargedCandidate(
                )  # instantiate a dummy RecoChargedCandidate
                ic.setCharge(il.charge())  # assign the correct charge
                ic.setP4(myp4)  # assign the correct p4
                ic.setTrack(il.track())  # set the correct TrackRef
                if ic.track().isNonnull(
                ):  # check that the track is valid, there are photons around too!
                    self.tofit.push_back(ic)

            # further sanity check: two *distinct* tracks
            if self.tofit.size(
            ) == 2 and self.tofit[0].track() != self.tofit[1].track():
                # fit it!
                svtree = self.vtxfit.Fit(self.tofit)  # actual vertex fitting
                # check that the vertex is good
                if not svtree.get().isEmpty() and svtree.get().isValid():
                    svtree.movePointerToTheTop()
                    sv = svtree.currentDecayVertex().get()
                    event.recoSv = makeRecoVertex(
                        sv, kinVtxTrkSize=2)  # need to do some gymastics

            if event.recoSv:
                # primary vertex
                pv = event.goodVertices[0]

                event.recoSv.disp3DFromBS = ROOT.VertexDistance3D().distance(
                    event.recoSv, pv)
                event.recoSv.disp3DFromBS_sig = event.recoSv.disp3DFromBS.significance(
                )

                # create an 'ideal' vertex out of the BS
                point = ROOT.reco.Vertex.Point(
                    event.beamspot.position().x(),
                    event.beamspot.position().y(),
                    event.beamspot.position().z(),
                )
                error = event.beamspot.covariance3D()
                chi2 = 0.
                ndof = 0.
                bsvtx = ROOT.reco.Vertex(point, error, chi2, ndof,
                                         2)  # size? say 3? does it matter?

                event.recoSv.disp2DFromBS = ROOT.VertexDistanceXY().distance(
                    event.recoSv, bsvtx)
                event.recoSv.disp2DFromBS_sig = event.recoSv.disp2DFromBS.significance(
                )
                event.recoSv.prob = ROOT.TMath.Prob(event.recoSv.chi2(),
                                                    int(event.recoSv.ndof()))

                dilep_p4 = event.the_hnl.l1().bestmatch.p4(
                ) + event.the_hnl.l2().bestmatch.p4()

                perp = ROOT.math.XYZVector(dilep_p4.px(), dilep_p4.py(), 0.)

                dxybs = ROOT.GlobalPoint(
                    -1 * ((event.beamspot.x0() - event.recoSv.x()) +
                          (event.recoSv.z() - event.beamspot.z0()) *
                          event.beamspot.dxdz()),
                    -1 * ((event.beamspot.y0() - event.recoSv.y()) +
                          (event.recoSv.z() - event.beamspot.z0()) *
                          event.beamspot.dydz()), 0)

                vperp = ROOT.math.XYZVector(dxybs.x(), dxybs.y(), 0.)

                cos = vperp.Dot(perp) / (vperp.R() * perp.R())

                event.recoSv.disp2DFromBS_cos = cos

#             if (abs(event.the_hnl.l1().pdgId()) == 11 or abs(event.the_hnl.l2().pdgId()) == 11):
#                 if (abs(event.the_hnl.l1().bestmatch.pdgId()) == 11 or abs(event.the_hnl.l2().bestmatch.pdgId()) == 11):
#                     if event.recoSv:
#                         print 'lept1      \t', event.the_hnl.l1()
#                         print 'lept2      \t', event.the_hnl.l2()
#                         print 'lept1 match\t', event.the_hnl.l1().bestmatch
#                         print 'lept2 match\t', event.the_hnl.l2().bestmatch
#                         import pdb ; pdb.set_trace()

        return True
Exemple #35
0
     mcmatch =  dict((d,[]) for d in matches )
     # first, match and remove the charged
     charged = [d for d in matches if d.charge() != 0]
     neutral = [d for d in matches if d.charge() == 0]
     ch_match = matchObjectCollection3( charged, c_tomatch, 0.07, filter = lambda d,g: abs(d.pt()-g.pt())/(d.pt()+g.pt()) < 0.2 )
     gen_notused = a_tomatch[:]
     reco_notused = matches[:]
     for c in charged:
         g = ch_match[c]
         if g == None: continue
         mcmatch[c] = [g]
         gen_notused.remove(g)
         reco_notused.remove(c)
     # then assign each gen to the nearest unmatched reco that has reco pt > 0.5 * gen pt
     for g in gen_notused[:]:
         d, dr2 = bestMatch(g, reco_notused)
         if dr2 < 0.01 and d.pt() > 0.5*g.pt(): 
             gen_notused.remove(g)
             mcmatch[d].append(g)
     # then take any remaining gen and just attach it to the nearest reco, except well-matched tracks
     rematch = neutral + [ c for c in charged if c in reco_notused ]
     for g in gen_notused:
         d, dr2 = bestMatch(g, rematch)
         if dr2 < 0.01: mcmatch[d].append(g) 
 matchletters = [ "X" for mm in matchmaps ]
 allmatches   = [ []  for mm in matchmaps ]
 for im,d in enumerate(matches):
     keyer[d.uid()] = "%s%02d" % (layerlabel,im)
     revkey["%s%02d" % (layerlabel,im)] = d
     if d.pt() < 0.8: continue
     print "  %s%02d  pt %6.2f  eta %+5.2f  phi %+5.2f  ch %+1d  dr %.2f  id % +5d" % (layerlabel,im, d.pt(), d.eta(), d.phi(), d.charge(), d.dr, d.pdgId()),