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
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
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
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
def __init__(self, diobject): super(DiMuon, self).__init__(diobject) self.mu1 = Muon(diobject.leg1()) self.mu2 = Muon(diobject.leg2())
def __init__(self, diobject): super(MuonElectron, self).__init__(diobject) self.mu = Muon(diobject.leg1()) self.ele = HTauTauElectron(diobject.leg2())
def __init__(self, diobject): super(TauMuon, self).__init__(diobject) self.tau = Tau(diobject.leg1()) self.mu = Muon(diobject.leg2())
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