コード例 #1
0
ファイル: TauTauAnalyzer.py プロジェクト: pcirkovic/cmg-cmssw
 def buildMuons(self, cmgLeptons, event):
     '''Build muons for veto, associate best vertex, select loose ID muons.
     The loose ID selection is done to ensure that the muon has an inner track.'''
     leptons = []
     for index, lep in enumerate(cmgLeptons):
         pyl = Muon(lep)
         pyl.associatedVertex = event.goodVertices[0]
         if not self.testMuonIDLoose(pyl):
             continue
         leptons.append(pyl)
     return leptons
コード例 #2
0
ファイル: TauTauAnalyzer.py プロジェクト: 12345ieee/cmg-cmssw
 def buildMuons(self, cmgLeptons, event):
     '''Build muons for veto, associate best vertex, select loose ID muons.
     The loose ID selection is done to ensure that the muon has an inner track.'''
     leptons = []
     for index, lep in enumerate(cmgLeptons):
         pyl = Muon(lep)
         pyl.associatedVertex = event.goodVertices[0]
         if not self.testMuonIDLoose( pyl ):
             continue
         leptons.append( pyl )
     return leptons
コード例 #3
0
ファイル: DiObject.py プロジェクト: pcirkovic/cmg-cmssw
 def __init__(self, diobject):
     super(TauMuon, self).__init__(diobject)
     self.tau = Tau(diobject.leg1())
     self.mu = Muon(diobject.leg2())
     #COLIN some of the matching stuff could go up
     self.leg1Gen = None
     self.leg2Gen = None
     self.leg1DeltaR = -1
     self.leg2DeltaR = -1
コード例 #4
0
ファイル: httanalyzerpftau.py プロジェクト: anantoni/CMG
    def process(self, iEvent, event):
        self.readCollections( iEvent )

        eventNumber = iEvent.eventAuxiliary().id().event()
#        print "========================================================="
#        print "event:",eventNumber
        
        myEvent = Event(event.iEv)
        setattr(event, self.name, myEvent)
        event = myEvent
        
        self.buildMCinfo( event )   

        self.counters.counter('h_gen').inc('All events')
        self.counters.counter('h_rec').inc('All events')
        if self.isHZ: self.counters.counter('h_gen').inc('All hz events')
        if len(self.tau)==2:
            self.counters.counter('h_gen').inc('h->tt')
            if self.isHZqq:
                self.counters.counter('h_gen').inc('Z->qq and h->tt')
                if self.isHZbb:
                    self.counters.counter('h_gen').inc('Z->bb and h->tt')

        event.isHZ = 0
        event.isHZqq = 0
        event.isHZbb = 0
        
        if self.isHZ:
            event.isHZ=1
            event.H=self.H
            event.Z=self.Z
            if self.isHZqq:
                event.isHZqq=1
            if self.isHZbb:
                event.isHZbb=1
            
        event.ishtt = 0

        if len(self.tau)==2:
            event.ishtt =1
            event.tau1=self.tau[0]
            event.tau2=self.tau[1]

        #save the two leading muons and the two leading electrons
        self.muons = []
        for muon in  self.handles['muons'].product():
          self.muons.append(Muon(muon))
        self.muons.sort(key=lambda a: a.energy(), reverse = True)  

        event.leadingMuon_en=-1
        if len(self.muons)>=1:
            event.leadingMuon_en=self.muons[0].energy()
            
        event.leadingMuons = []
        for muon in self.muons:
          if len(event.leadingMuons) >= 2: break
          event.leadingMuons.append(muon)
          # this is needed because the energy of the muon is changed later on if it is a tau candidate
          
        self.electrons = []
        for electron in  self.handles['electrons'].product():
          self.electrons.append(Electron(electron))   
        self.electrons.sort(key=lambda a: a.energy(), reverse = True)

        event.leadingElectron_en=-1
        if len(self.electrons)>=1:
            event.leadingElectron_en=self.electrons[0].energy()

        event.leadingElectrons = []
        for electron in self.electrons:
          if len(event.leadingElectrons) >= 2: break
          event.leadingElectrons.append(electron)   

        self.hadtaus = []
        for tau in  self.handles['taus'].product():
          self.hadtaus.append(Tau(tau))   
        self.hadtaus.sort(key=lambda a: a.energy(), reverse = True)
    
        
        # prepare jets ordered in energy
        self.jets=[]
        for ptj in self.handles['jets'].product():
            self.jets.append(Jet(ptj))
            
        # order them in energy
        self.jets.sort(key=lambda a: a.energy(), reverse = True)
        event.njets=len(self.jets)
        

        # loop over ele,muo,hadtaus and define  "isolation", and jetindex
        # iso is the closest jet (excluding itself) distance
        # index is the pfjet index of the object (ele,muo,tau)
        # dist is the distance of the object to the matched pfjet (it is trivially 1 for pfjets)
        
        self.jetiso,self.jetindex,self.jetdist=self.findiso(self.jets,self.jets)
        self.muoiso,self.muoindex,self.muodist=self.findiso(self.jets,self.muons)
        self.eleiso,self.eleindex,self.eledist=self.findiso(self.jets,self.electrons)
        self.hadtauiso,self.hadtauindex,self.hadtaudist=self.findiso(self.jets,self.hadtaus)


        # look now at the tau jets
        self.taugenjet=[]
        self.taucos=[]
        self.tauiso=[]
        self.taumatchingjetindex=[]

#        self.nontaugenjet = copy.copy(self.jets)
#        self.nontaugenjetiso = copy.copy(self.jetiso)
       
        if event.ishtt==1:

            # loop over jets and find closest gen tau
            if event.njets>=2:
                for thistau in self.tau:
                    cosmax=-2
                    tauindex=-10
                    for ind in range(0,len(self.jets)):
                        thisjet=self.jets[ind]
                        thiscos=self.cosdelta(thistau,thisjet)
                        if thiscos>cosmax:
                            cosmax=thiscos
                            taucand=thisjet
                            iso=self.jetiso[ind]
                            tauindex=ind
                            
                    if cosmax!=-2:        
                        self.taugenjet.append(taucand)
                        self.tauiso.append(iso)
                        #self.nontaugenjet.pop(tauindex)
                        #self.nontaugenjetiso.pop(tauindex)
                        self.taumatchingjetindex.append(tauindex)
                    else:
                        self.taugenjet.append(thistau) # just to fill it up
                    self.taucos.append(cosmax)
    
                        
    
                event.tau1genjet = self.taugenjet[0]
                event.tau1cosjet = self.taucos[0]
                event.tau1iso = self.tauiso[0]
                event.tau2genjet = self.taugenjet[1]
                event.tau2cosjet = self.taucos[1]
                event.tau2iso = self.tauiso[1]
                event.tau1matchingjetindex=self.taumatchingjetindex[0]
                event.tau2matchingjetindex=self.taumatchingjetindex[1]


#        self.nontaugenjet.sort(key=lambda a: a.energy(), reverse = True)
#        event.nontaugenjet = self.nontaugenjet
#        event.nontaugenjetiso = self.nontaugenjetiso
        
        
        
        # debug
#        if event.ishtt==1 and event.isHZqq==1:
#            print "tau gen:"
#
#            print event.tau1
#            print event.tau2
#            
#            print "jets"
#            for jet in self.jets:
#                print jet
#            print "muons"
#            for jet in self.muons:
#                print jet
#            print "electrons"
#            for jet in self.electrons:
#                print jet
#            print "taus"
#            for jet in self.hadtaus:
#                print jet
            

        # start here the real selection
        event.step=0
        event.matchedRecGenDistances = []
        event.hz = []
        
        # first look for at least four jets and two of them isolated and low #tracks
        if event.njets<4:
            return
        event.step+=1 # 1
        
        #test for jets above threshold
        etest = self.testE()
        if etest:
          self.counters.counter('h_rec').inc('4 jets above threshold')
        else:
          return
        event.step+=1 #2



#        print "njets=",event.njets,len(self.jets)
        # requires at least 2 taucandidates as isolated jets (0.5) and with 1 or 3 tracks
        event.taucand=[]
        event.taucandtype=[]
        event.taucandiso=[]
        event.taucandindex=[]
        event.taucandcharge=[]
        event.nontaucand=[]
        event.nontaucandiso=[]
        event.acoll = -99.
        event.acopl = -99.

        removedjet=[]
        
        # first build up tau dandidates from hadtaus, electrons and muons
        #        print "#jets,muons,elec,hadtaus:",len(self.jets),len(self.muons),len(self.electrons),len(self.hadtaus)
        for ind in range(0,len(self.muons)):
            if self.testmuoId(ind):
                if self.muoindex[ind] not in removedjet: # be sure you get only one copy
                    event.taucand.append(self.muons[ind])
                    event.taucandtype.append(0)
                    event.taucandiso.append(self.muoiso[ind])
                    event.taucandindex.append(self.muoindex[ind])
                    removedjet.append(self.muoindex[ind])
                    # print "added muon ",event.taucandindex[len(event.taucand)-1]

        for ind in range(0,len(self.electrons)):
            if self.testeleId(ind):
                if self.eleindex[ind] not in removedjet: # prefer muons over ele if belonging to same matched jet
                    event.taucand.append(self.electrons[ind])
                    event.taucandtype.append(1)
                    event.taucandiso.append(self.eleiso[ind])
                    event.taucandindex.append(self.eleindex[ind])
                    removedjet.append(self.eleindex[ind])
                    # print "added ele ",event.taucandindex[len(event.taucand)-1]

        for ind in range(0,len(self.hadtaus)):
            if self.testhadtauId(ind):
                if self.hadtauindex[ind] not in removedjet: # prefer electrons,muons over had taus if belonging to same matched jet
                    event.taucand.append(self.hadtaus[ind])
                    event.taucandtype.append(2)
                    event.taucandiso.append(self.hadtauiso[ind])
                    event.taucandindex.append(self.hadtauindex[ind])
                    removedjet.append(self.hadtauindex[ind])
                    # print "added hadtau ",event.taucandindex[len(event.taucand)-1]

                

        # now we can add the jets not associated to candidate taus (ele, muo, hadtau) to the jet list                
        for ind in range(0,len(self.jets)):
            if ind not in removedjet: 
                event.nontaucand.append(self.jets[ind])
                event.nontaucandiso.append(self.jetiso[ind])
                # print "added jet ",event.nontaucand[len(event.nontaucand)-1].energy()
                
        



        # check for 2 tau candidates
        if len(event.taucand)<2:
            return
        self.counters.counter('h_rec').inc('2 tau candidates')    
        event.step+=1 #3

        if len(event.taucand)==2:
            #electrons + muons + charged hadrons
            ntr1=self.ntrtaucand(event.taucand[0],event.taucandtype[0])
            ntr2=self.ntrtaucand(event.taucand[1],event.taucandtype[1])
            if (ntr1*ntr2)!=1 and (ntr1*ntr2)!=3:
                return
        # now iterate on all possible pairs of tau candidates, if more than two, and keep only the ones which give
        # opposite mass closer to Z peak

        if len(event.taucand)>2:
            dm=9999.
            taupair=(-1,-1)
            # fit version of tau finding optimization
            for ind1, ind2 in itertools.combinations(range(len(event.taucand)), 2):
                ntr1=self.ntrtaucand(event.taucand[0],event.taucandtype[0])
                ntr2=self.ntrtaucand(event.taucand[1],event.taucandtype[1])

                # consider only combination 1,1 1,3 3,1
                if (ntr1*ntr2)!=1 and (ntr1*ntr2)!=3:
                    continue
                nt=[]
                nj=[]
                nt.append(event.taucand[ind1])
                nt.append(event.taucand[ind2])
                nj=copy.copy(event.nontaucand)
                for i in range(len(event.taucand)):
                    if i!=ind1 and i!=ind2:
                        nj.append(self.jets[event.taucandindex[i]])

                # nt and nj are potential tau and nontaucandidates
                # now clusterize the nontaucand
                tmpJets=list(self.buildClusteredJets(nj))
                # poor man kf
                chi2,newjets,newtaus = self.beta4(tmpJets, nt, 120.,False)

                jet0=newjets[0]
                jet1=newjets[1]
                
                mnontau=(jet0[3]+jet1[3])**2-(jet0[2]+jet1[2])**2-(jet0[1]+jet1[1])**2-(jet0[0]+jet1[0])**2
                if mnontau>0:
                    mnontau=sqrt(mnontau)
                else:
                    mnontau=0
#                print ind1,ind2,mnontau
                if abs(mnontau-91.2)<dm:
                    taupair=(ind1,ind2)
                    dm=abs(mnontau-91.2)
                
                
                


            # now we have taupair and we can adapt the candidates
            (t1,t2)=taupair
#            print "chosen",t1,t2

            if t1<0 or t2<0:
                return
#            print "chosen",t1,t2
            t1temp=event.taucand[t1]
            t1isotemp=event.taucandiso[t1]
            t1typetemp=event.taucandtype[t1]
            t1indextemp=event.taucandindex[t1]

            t2temp=event.taucand[t2]
            t2isotemp=event.taucandiso[t2]
            t2typetemp=event.taucandtype[t2]
            t2indextemp=event.taucandindex[t2]
            
            for tauind in range(0,len(event.taucand)):
                if tauind!=t1 and tauind!=t2:
                    #remove thsi tau candidate and add it to nontaucandidate
                    # print "removing ",tauind
                    event.nontaucand.append(self.jets[event.taucandindex[tauind]])
                    event.nontaucandiso.append(self.jetiso[event.taucandindex[tauind]])
            # cleanup the taucand list
            event.taucand=[t1temp,t2temp]
            event.taucandiso=[t1isotemp,t2isotemp]
            event.taucandtype=[t1typetemp,t2typetemp]
            event.taucandindex=[t1indextemp,t2indextemp]


        self.counters.counter('h_rec').inc('2 tau candidates good pair')    
        event.step+=1 #4

        
        #fill jet charges for tau candidates
#        for tau in event.taucand:
#          print tau.numberOfSourceCandidatePtrs()
#          constituents = tau.sourcePtr().getPFConstituents()
#          charge = 0
#          for constituent in constituents:
#             charge += constituent.charge()
#          event.taucandcharge.append[charge]
        #fill acollinearity for tau candidates
        tnorm1 = event.taucand[0].p4().P()
        tnorm2 = event.taucand[1].p4().P()
        ttdot = event.taucand[0].px()*event.taucand[1].px() + event.taucand[0].py()*event.taucand[1].py() + event.taucand[0].pz()*event.taucand[1].pz()
        event.acoll = ttdot/(tnorm1*tnorm2)   
   
            
        #MC matching
        if event.ishtt==1 and event.isHZqq==1:
            #check the closest gen tau
            self.matched=[]
            self.matcheddistance=[]
            for taucand in event.taucand:
                    cosmax=-2
                    for gentau in self.tau:
                        thiscos=self.cosdelta(taucand,gentau)
                        if thiscos>cosmax:
                            cosmax=thiscos
                    event.matchedRecGenDistances.append(cosmax)     
  
        #cluster the remaining part of the event

        #        self.buildClusteredJets_old(event)
        tmpJets=self.buildClusteredJets(event.nontaucand)
        # rewrites the jets after clustering
        event.nontaucand = []
        for jet in tmpJets:
            event.nontaucand.append(jet)

        # debug
#        if event.ishtt==1 and event.isHZqq==1:
#            print "tau cand"
#            for jet in event.taucand:
#                print jet
#            print "non taucand"
#            for jet in event.nontaucand:
#                print jet



        jnorm1 = event.nontaucand[0].p4().P()    
        jnorm2 = event.nontaucand[1].p4().P()    
        jjdot = event.nontaucand[0].px()*event.nontaucand[1].px() + event.nontaucand[0].py()*event.nontaucand[1].py() + event.nontaucand[0].pz()*event.nontaucand[1].pz()  
        event.jcoll = jjdot/(jnorm1*jnorm2)

        event.btag_tt=0
        event.btag_jj=0
#        for jet in event.taucand:
#            event.btag_tt+=jet.btag(7)
        for jet in event.nontaucand:
            event.btag_jj+=jet.btag(7)
        

        # store variables before rescaling
        event.t1_px=event.taucand[0].px()
        event.t1_py=event.taucand[0].py()
        event.t1_pz=event.taucand[0].pz()
        event.t1_en=event.taucand[0].energy()
        event.t2_px=event.taucand[1].px()
        event.t2_py=event.taucand[1].py()
        event.t2_pz=event.taucand[1].pz()
        event.t2_en=event.taucand[1].energy()
        
        # store variables before rescaling
        event.j1_px=event.nontaucand[0].px()
        event.j1_py=event.nontaucand[0].py()
        event.j1_pz=event.nontaucand[0].pz()
        event.j1_en=event.nontaucand[0].energy()
        event.j2_px=event.nontaucand[1].px()
        event.j2_py=event.nontaucand[1].py()
        event.j2_pz=event.nontaucand[1].pz()
        event.j2_en=event.nontaucand[1].energy()
        
#        print "before rescaling:",event.t1_en,event.t2_en,event.j1_en,event.j2_en
#        print "before rescaling from jet:",self.jets[event.taucandindex[0]].energy(),self.jets[event.taucandindex[1]].energy()
        
        #check that the clustered jets pass id (this also does the momentum rescaling)

        idpass,newjets,newtaus = self.testId(event.nontaucand, event.taucand,True)

        # we need also to replace self.jets px,py,pz (will be used for findww,findzz and findhz)
        for ind in range(0,len(event.taucand)):
            j_ind=event.taucandindex[ind]
            p4=self.jets[j_ind].p4()
            p4.SetPxPyPzE(event.taucand[ind].px(),event.taucand[ind].py(),event.taucand[ind].pz(),event.taucand[ind].energy())
            self.jets[j_ind].setP4(p4)

        
        #fill acoplanarity between met and the plane containinf the taus
        t1 = numpy.array([event.taucand[0].px(), event.taucand[0].py(), event.taucand[0].pz()])
        t2 = numpy.array([event.taucand[1].px(), event.taucand[1].py(), event.taucand[1].pz()])
        norm = numpy.cross(t1,t2)
        #now extract the angle wrt mmissing energy
        me = ([-self.px, -self.py, -self.pz])
        pscal = numpy.dot(norm,me)
        norm_p = numpy.linalg.norm(norm)
        me_p = numpy.linalg.norm(me)
        if norm_p>0 and me_p>0:
          event.acopl = pscal/(norm_p * me_p)


        # store variables after rescaling
        event.t1s_px=event.taucand[0].px()
        event.t1s_py=event.taucand[0].py()
        event.t1s_pz=event.taucand[0].pz()
        event.t1s_en=event.taucand[0].energy()
        event.t2s_px=event.taucand[1].px()
        event.t2s_py=event.taucand[1].py()
        event.t2s_pz=event.taucand[1].pz()
        event.t2s_en=event.taucand[1].energy()
        
        # store variables after rescaling
        event.j1s_px=event.nontaucand[0].px()
        event.j1s_py=event.nontaucand[0].py()
        event.j1s_pz=event.nontaucand[0].pz()
        event.j1s_en=event.nontaucand[0].energy()
        event.j2s_px=event.nontaucand[1].px()
        event.j2s_py=event.nontaucand[1].py()
        event.j2s_pz=event.nontaucand[1].pz()
        event.j2s_en=event.nontaucand[1].energy()

#        print "after rescaling:",event.t1s_en,event.t2s_en,event.j1s_en,event.j2s_en
#        print "after rescaling from jet:",self.jets[event.taucandindex[0]].energy(),self.jets[event.taucandindex[1]].energy()


        event.mvis = self.mvis
        event.px = self.px
        event.py = self.py
        event.pz = self.pz
        event.evis = self.evis
        event.chi2 = self.chi2
        event.mmin = self.mmin

        event.alljets=[]
        # print "alljets",len(self.jets),event.taucandindex[0],event.taucandindex[1]
        
        # this is needed to use findXX (for Diobject, otherwise btag is not defined)
        event.taucandjets=[self.jets[event.taucandindex[0]],self.jets[event.taucandindex[1]]]


        for jet in event.nontaucand:
            event.alljets.append(jet)
        for jet in event.taucandjets:
            event.alljets.append(jet)
            
        #event.alljets contains all jets now (j1,j2,t1,t2)
        event.jetPairs = self.findPairs( event.alljets )
        event.ww, event.wwMin = self.findWW ( event.jetPairs )
        event.zz, event.zzMin = self.findZZ ( event.jetPairs )


        if not idpass:
          return

        self.counters.counter('h_rec').inc('2 jets with id')
        event.step+=1 #5

        


        #finally find the HZ candidates
        reshz,self.hz = self.findHZ(event.nontaucand, event.taucandjets)
        event.hz = self.hz
#        print "dijetmass ",event.hz[1].M()
        if not reshz:
          return
        event.step+=1 #6
        self.counters.counter('h_rec').inc('passed') 

        if event.ishtt==1 and event.isHZqq==1:
            self.counters.counter('h_gen').inc('Z->qq and h->tt selected')
        if event.ishtt==1 and event.isHZbb==1:
            self.counters.counter('h_gen').inc('Z->bb and h->tt selected')
            
        # apply btag here
        if event.btag_jj<0.95:
            return
        event.step+=1 #7
        if event.ishtt==1 and event.isHZqq==1:
            self.counters.counter('h_gen').inc('Z->qq and h->tt b-selected')
        if event.ishtt==1 and event.isHZbb==1:
            self.counters.counter('h_gen').inc('Z->bb and h->tt b-selected')
        
        

        return True
コード例 #5
0
 def __init__(self, diobject):
     super(DiMuon, self).__init__(diobject)
     self.mu1 = Muon(diobject.leg1())
     self.mu2 = Muon(diobject.leg2())
コード例 #6
0
 def __init__(self, diobject):
     super(MuonElectron, self).__init__(diobject)
     self.mu = Muon(diobject.leg1())
     self.ele = HTauTauElectron(diobject.leg2())
コード例 #7
0
 def __init__(self, diobject):
     super(TauMuon, self).__init__(diobject)
     self.tau = Tau(diobject.leg1())
     self.mu = Muon(diobject.leg2())
コード例 #8
0
    def process(self, iEvent, event):
        self.readCollections(iEvent)

        eventNumber = iEvent.eventAuxiliary().id().event()
        myEvent = Event(event.iEv)
        setattr(event, self.name, myEvent)
        event = myEvent

        self.buildMCinfo(event)

        self.counters.counter('h_gen').inc('All events')
        self.counters.counter('h_rec').inc('All events')
        if self.isHZ: self.counters.counter('h_gen').inc('All hz events')
        if len(self.tau) == 2:
            self.counters.counter('h_gen').inc('h->tt')
            if self.isHZqq:
                self.counters.counter('h_gen').inc('Z->qq and h->tt')
                if self.isHZbb:
                    self.counters.counter('h_gen').inc('Z->bb and h->tt')

        event.isHZ = 0
        event.isHZqq = 0
        event.isHZbb = 0

        if self.isHZ:
            event.isHZ = 1
            event.H = self.H
            event.Z = self.Z
            if self.isHZqq:
                event.isHZqq = 1
            if self.isHZbb:
                event.isHZbb = 1

        event.ishtt = 0

        if len(self.tau) == 2:
            event.ishtt = 1
            event.tau1 = self.tau[0]
            event.tau2 = self.tau[1]

        #save the two leading muons and the two leading electrons
        self.muons = []
        for muon in self.handles['muons'].product():
            self.muons.append(Muon(muon))
        self.muons.sort(key=lambda a: a.energy(), reverse=True)
        event.leadingMuons = []
        for muon in self.muons:
            if len(event.leadingMuons) >= 2: break
            event.leadingMuons.append(muon)

        self.electrons = []
        for electron in self.handles['electrons'].product():
            self.electrons.append(Electron(electron))
        self.electrons.sort(key=lambda a: a.energy(), reverse=True)
        event.leadingElectrons = []
        for electron in self.electrons:
            if len(event.leadingElectrons) >= 2: break
            event.leadingElectrons.append(electron)

        # prepare jets ordered in energy
        self.jets = []
        for ptj in self.handles['jets'].product():
            self.jets.append(Jet(ptj))

        # order them in energy
        self.jets.sort(key=lambda a: a.energy(), reverse=True)
        event.njets = len(self.jets)

        # loop over jets and define  "isolation"
        self.jetiso = []
        for ind1 in range(0, len(self.jets)):
            cosmax = -2
            for ind2 in range(ind1 + 1, len(self.jets)):
                cos = self.cosdelta(self.jets[ind1], self.jets[ind2])
                if cos > cosmax:
                    cosmax = cos
            self.jetiso.append(cosmax)

#        # prepare electrons ordered in energy
#        self.electrons=[]
#        for ptj in self.handles['electrons'].product():
#            self.electrons.append(Electron(ptj))
#
#        # order them in energy
#        self.electrons.sort(key=lambda a: a.energy(), reverse = True)
#
#        # loop over electron and define  "isolation"
#        self.eleiso=[]
#        for ind1 in range(0,len(self.electrons)):
#            cosmax=-2
#            for ind2 in range(ind1+1,len(self.jets)):
#                cos=self.cosdelta(self.electrons[ind1],self.jets[ind2])
#                if cos> cosmax:
#                    cosmax=cos
#            self.eleiso.append(cosmax)
#
#        # prepare muons ordered in energy
#        self.muons=[]
#        for ptj in self.handles['muons'].product():
#            self.muons.append(Electron(ptj))
#
#        # order them in energy
#        self.muons.sort(key=lambda a: a.energy(), reverse = True)
#
#        # loop over jets and define  "isolation"
#        self.muoiso=[]
#        for ind1 in range(0,len(self.muons)):
#            cosmax=-2
#            for ind2 in range(ind1+1,len(self.jets)):
#                cos=self.cosdelta(self.muons[ind1],self.jets[ind2])
#                if cos> cosmax:
#                    cosmax=cos
#            self.muoiso.append(cosmax)

# look now at the tau jets
        self.taugenjet = []
        self.taucos = []
        self.tauiso = []
        self.taumatchingjetindex = []

        #        self.nontaugenjet = copy.copy(self.jets)
        #        self.nontaugenjetiso = copy.copy(self.jetiso)

        if event.ishtt == 1:

            # loop over jets and find closest gen tau
            if event.njets >= 2:
                for thistau in self.tau:
                    cosmax = -2
                    tauindex = -10
                    for ind in range(0, len(self.jets)):
                        thisjet = self.jets[ind]
                        thiscos = self.cosdelta(thistau, thisjet)
                        if thiscos > cosmax:
                            cosmax = thiscos
                            taucand = thisjet
                            iso = self.jetiso[ind]
                            tauindex = ind

                    if cosmax != -2:
                        self.taugenjet.append(taucand)
                        self.tauiso.append(iso)
                        #self.nontaugenjet.pop(tauindex)
                        #self.nontaugenjetiso.pop(tauindex)
                        self.taumatchingjetindex.append(tauindex)
                    else:
                        self.taugenjet.append(thistau)  # just to fill it up
                    self.taucos.append(cosmax)

                event.tau1genjet = self.taugenjet[0]
                event.tau1cosjet = self.taucos[0]
                event.tau1iso = self.tauiso[0]
                event.tau2genjet = self.taugenjet[1]
                event.tau2cosjet = self.taucos[1]
                event.tau2iso = self.tauiso[1]
                event.tau1matchingjetindex = self.taumatchingjetindex[0]
                event.tau2matchingjetindex = self.taumatchingjetindex[1]

#        self.nontaugenjet.sort(key=lambda a: a.energy(), reverse = True)
#        event.nontaugenjet = self.nontaugenjet
#        event.nontaugenjetiso = self.nontaugenjetiso

# start here the real selection
        event.step = 0
        event.matchedRecGenDistances = []
        event.hz = []

        # first look for at least four jets and two of them isolated and low #tracks
        if event.njets < 4:
            return
        event.step += 1  # 1

        #test for jets above threshold
        etest = self.testE()
        if etest:
            self.counters.counter('h_rec').inc('4 jets above threshold')
        else:
            return
        event.step += 1  #2

        #        print "njets=",event.njets,len(self.jets)
        # requires at least 2 taucandidates as isolated jets (0.5) and with 1,2 or 3 tracks
        event.taucand = []
        event.taucandiso = []
        event.taucandcharge = []
        event.nontaucand = []
        event.nontaucandiso = []
        event.acoll = -99.
        event.acopl = -99.
        for ind in range(0, len(self.jets)):
            #            print "evaluating ",ind
            #            ntrk=self.jets[ind].component(1).number()
            # the two most energetic jets are not considered among taus
            #            if ind>=2 and ntrk>0 and ntrk<=3  and self.jetiso[ind]<0.5 and len(event.taucand)<2:
            #            if ntrk>=1 and ntrk<=3  and self.jetiso[ind]<0.8 and len(event.taucand)<2:
            # if ntrk>=0 and ntrk<=3  and self.jetiso[ind]<0.5 and len(event.taucand)<2:
            # if ntrk>=1 and ntrk<=3  and self.jetiso[ind]<0.9:
            #            if ntrk>=1 and ntrk<=3:
            #            if ntrk==1 or ntrk==3:
            if self.testTauId(self.jets[ind]):
                event.taucand.append(self.jets[ind])
                event.taucandiso.append(self.jetiso[ind])
#                print "adding to tau"
            else:
                event.nontaucand.append(self.jets[ind])
                event.nontaucandiso.append(self.jetiso[ind])
                #                print "adding to non tau"

        # check for 2 tau candidates
        if len(event.taucand) < 2:
            return
        self.counters.counter('h_rec').inc('2 tau candidates')
        event.step += 1  #3

        if len(event.taucand) == 2:
            #electrons + muons + charged hadrons
            ntr1 = event.taucand[0].component(
                1).number() + event.taucand[0].component(
                    2).number() + event.taucand[0].component(3).number()
            ntr2 = event.taucand[1].component(
                1).number() + event.taucand[1].component(
                    2).number() + event.taucand[1].component(3).number()
            if (ntr1 * ntr2) != 1 and (ntr1 * ntr2) != 3:
                return
        # now iterate on all possible pairs of tau candidates, if more than two, and keep only the ones which give
        # opposite mass closer to Z peak

        if len(event.taucand) > 2:
            dm = 9999.
            taupair = (-1, -1)
            # fit version of tau finding optimization
            for ind1, ind2 in itertools.combinations(range(len(event.taucand)),
                                                     2):
                ntr1 = event.taucand[ind1].component(
                    1).number() + event.taucand[ind1].component(2).number(
                    ) + event.taucand[ind1].component(3).number()
                ntr2 = event.taucand[ind2].component(
                    1).number() + event.taucand[ind2].component(2).number(
                    ) + event.taucand[ind2].component(3).number()
                # consider only combination 1,1 1,3 3,1

                if (ntr1 * ntr2) != 1 and (ntr1 * ntr2) != 3:
                    continue
                nt = []
                nj = []
                nt.append(event.taucand[ind1])
                nt.append(event.taucand[ind2])
                nj = copy.copy(event.nontaucand)
                for i in range(len(event.taucand)):
                    if i != ind1 and i != ind2:
                        nj.append(event.taucand[i])
                # nt and nj are potential tau and nontaucandidates
                # now clusterize the nontaucand
                tmpJets = list(self.buildClusteredJets(nj))
                # poor man kf
                chi2, newjets, newtaus = self.beta4(tmpJets, nt, 120., False)

                jet0 = newjets[0]
                jet1 = newjets[1]

                mnontau = (jet0[3] + jet1[3])**2 - (jet0[2] + jet1[2])**2 - (
                    jet0[1] + jet1[1])**2 - (jet0[0] + jet1[0])**2
                if mnontau > 0:
                    mnontau = sqrt(mnontau)
                else:
                    mnontau = 0
#                print ind1,ind2,mnontau
                if abs(mnontau - 91.2) < dm:
                    taupair = (ind1, ind2)
                    dm = abs(mnontau - 91.2)

            # poor man optimization of tau candidates
            # first sum-up nontaucand momentum
#            pnontau=[0,0,0,0]
#            for jet in event.nontaucand:
#                pnontau[0]+=jet.px()
#                pnontau[1]+=jet.py()
#                pnontau[2]+=jet.pz()
#                pnontau[3]+=jet.energy()
#            for ind1, ind2 in itertools.combinations(range(len(event.taucand)), 2):
#                ntr1=event.taucand[ind1].component(1).number()
#                ntr2=event.taucand[ind2].component(1).number()
#                if (ntr1*ntr2)!=1 and (ntr1*ntr2)!=3:
#                    continue
#                ptau=[0,0,0,0]
#                for tauind in range(0,len(event.taucand)):
#                    if tauind!=ind1 and tauind!=ind2:
#                        ptau[0]+=event.taucand[tauind].px()
#                        ptau[1]+=event.taucand[tauind].py()
#                        ptau[2]+=event.taucand[tauind].pz()
#                        ptau[3]+=event.taucand[tauind].energy()
#                pall=[0,0,0,0]
#                for comp in range(0,4): pall[comp]=pnontau[comp]+ptau[comp]
#                mnontau=pall[3]**2-pall[0]**2-pall[1]**2-pall[2]**2
#                if mnontau<0: mnontau=0
#                mnontau=sqrt(mnontau)
#                # print ind1,ind2,mnontau
#                if abs(mnontau-91.2)<dm:
#                    taupair=(ind1,ind2)
#                    dm=abs(mnontau-91.2)

# now we have taupair and we can adapt the candidates
            (t1, t2) = taupair
            #            print "chosen",t1,t2

            if t1 < 0 or t2 < 0:
                return
#            print "chosen",t1,t2
            t1temp = event.taucand[t1]
            t1isotemp = event.taucandiso[t1]
            t2temp = event.taucand[t2]
            t2isotemp = event.taucandiso[t2]

            for tauind in range(0, len(event.taucand)):
                if tauind != t1 and tauind != t2:
                    #remove thsi tau candidate and add it to nontaucandidate
                    # print "removing ",tauind
                    event.nontaucand.append(event.taucand[tauind])
                    event.nontaucandiso.append(event.taucandiso[tauind])
            # cleanup the taucand list
            event.taucand = [t1temp, t2temp]
            event.taucandiso = [t1isotemp, t2isotemp]

        self.counters.counter('h_rec').inc('2 tau candidates good pair')
        event.step += 1  #4
        #fill jet charges for tau candidates
        #        for tau in event.taucand:
        #          print tau.numberOfSourceCandidatePtrs()
        #          constituents = tau.sourcePtr().getPFConstituents()
        #          charge = 0
        #          for constituent in constituents:
        #             charge += constituent.charge()
        #          event.taucandcharge.append[charge]
        #fill acollinearity for tau candidates
        tnorm1 = event.taucand[0].p4().P()
        tnorm2 = event.taucand[1].p4().P()
        ttdot = event.taucand[0].px() * event.taucand[1].px(
        ) + event.taucand[0].py() * event.taucand[1].py(
        ) + event.taucand[0].pz() * event.taucand[1].pz()
        event.acoll = ttdot / (tnorm1 * tnorm2)

        #MC matching
        if event.ishtt == 1 and event.isHZqq == 1:
            #check the closest gen tau
            self.matched = []
            self.matcheddistance = []
            for taucand in event.taucand:
                cosmax = -2
                for gentau in self.tau:
                    thiscos = self.cosdelta(taucand, gentau)
                    if thiscos > cosmax:
                        cosmax = thiscos
                event.matchedRecGenDistances.append(cosmax)

        #cluster the remaining part of the event

        #        self.buildClusteredJets_old(event)
        tmpJets = self.buildClusteredJets(event.nontaucand)
        # rewrites the jets after clustering
        event.nontaucand = []
        for jet in tmpJets:
            event.nontaucand.append(jet)
        jnorm1 = event.nontaucand[0].p4().P()
        jnorm2 = event.nontaucand[1].p4().P()
        jjdot = event.nontaucand[0].px() * event.nontaucand[1].px(
        ) + event.nontaucand[0].py() * event.nontaucand[1].py(
        ) + event.nontaucand[0].pz() * event.nontaucand[1].pz()
        event.jcoll = jjdot / (jnorm1 * jnorm2)

        event.btag_tt = 0
        event.btag_jj = 0
        for jet in event.taucand:
            event.btag_tt += jet.btag(7)
        for jet in event.nontaucand:
            event.btag_jj += jet.btag(7)

        # store variables before rescaling
        event.t1_px = event.taucand[0].px()
        event.t1_py = event.taucand[0].py()
        event.t1_pz = event.taucand[0].pz()
        event.t1_en = event.taucand[0].energy()
        event.t2_px = event.taucand[1].px()
        event.t2_py = event.taucand[1].py()
        event.t2_pz = event.taucand[1].pz()
        event.t2_en = event.taucand[1].energy()

        # store variables before rescaling
        event.j1_px = event.nontaucand[0].px()
        event.j1_py = event.nontaucand[0].py()
        event.j1_pz = event.nontaucand[0].pz()
        event.j1_en = event.nontaucand[0].energy()
        event.j2_px = event.nontaucand[1].px()
        event.j2_py = event.nontaucand[1].py()
        event.j2_pz = event.nontaucand[1].pz()
        event.j2_en = event.nontaucand[1].energy()

        #check that the clustered jets pass id (this also does the momentum rescaling)

        idpass, newjets, newtaus = self.testId(event.nontaucand, event.taucand,
                                               True)
        #fill acoplanarity between met and the plane containinf the taus
        t1 = numpy.array([
            event.taucand[0].px(), event.taucand[0].py(),
            event.taucand[0].pz()
        ])
        t2 = numpy.array([
            event.taucand[1].px(), event.taucand[1].py(),
            event.taucand[1].pz()
        ])
        norm = numpy.cross(t1, t2)
        #now extract the angle wrt mmissing energy
        me = ([-self.px, -self.py, -self.pz])
        pscal = numpy.dot(norm, me)
        norm_p = numpy.linalg.norm(norm)
        me_p = numpy.linalg.norm(me)
        if norm_p > 0 and me_p > 0:
            event.acopl = pscal / (norm_p * me_p)

        # store variables after rescaling
        event.t1s_px = event.taucand[0].px()
        event.t1s_py = event.taucand[0].py()
        event.t1s_pz = event.taucand[0].pz()
        event.t1s_en = event.taucand[0].energy()
        event.t2s_px = event.taucand[1].px()
        event.t2s_py = event.taucand[1].py()
        event.t2s_pz = event.taucand[1].pz()
        event.t2s_en = event.taucand[1].energy()

        # store variables after rescaling
        event.j1s_px = event.nontaucand[0].px()
        event.j1s_py = event.nontaucand[0].py()
        event.j1s_pz = event.nontaucand[0].pz()
        event.j1s_en = event.nontaucand[0].energy()
        event.j2s_px = event.nontaucand[1].px()
        event.j2s_py = event.nontaucand[1].py()
        event.j2s_pz = event.nontaucand[1].pz()
        event.j2s_en = event.nontaucand[1].energy()

        event.mvis = self.mvis
        event.px = self.px
        event.py = self.py
        event.pz = self.pz
        event.evis = self.evis
        event.chi2 = self.chi2
        event.mmin = self.mmin

        event.alljets = []
        for jet in event.nontaucand:
            event.alljets.append(jet)
        for jet in event.taucand:
            event.alljets.append(jet)
        #event.alljets contains all jets now (j1,j2,t1,t2)
        event.jetPairs = self.findPairs(event.alljets)
        event.ww, event.wwMin = self.findWW(event.jetPairs)
        event.zz, event.zzMin = self.findZZ(event.jetPairs)

        if not idpass:
            return

        self.counters.counter('h_rec').inc('2 jets with id')
        event.step += 1  #5

        #finally find the HZ candidates
        reshz, self.hz = self.findHZ(event.nontaucand, event.taucand)
        event.hz = self.hz
        #        print "dijetmass ",event.hz[1].M()
        if not reshz:
            return
        event.step += 1  #6
        self.counters.counter('h_rec').inc('passed')

        if event.ishtt == 1 and event.isHZqq == 1:
            self.counters.counter('h_gen').inc('Z->qq and h->tt selected')
        if event.ishtt == 1 and event.isHZbb == 1:
            self.counters.counter('h_gen').inc('Z->bb and h->tt selected')

        # apply btag here
        if event.btag_jj < 0.95:
            return
        event.step += 1  #7
        if event.ishtt == 1 and event.isHZqq == 1:
            self.counters.counter('h_gen').inc('Z->qq and h->tt b-selected')
        if event.ishtt == 1 and event.isHZbb == 1:
            self.counters.counter('h_gen').inc('Z->bb and h->tt b-selected')

        return True