def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" electrons = Collection(event, "Electron") muons = Collection(event, "Muon") jets = Collection(event, "Jet") njets = len(jets) mht = ROOT.TLorentzVector() for lep in filter(self.muSel, muons): mht += lep.p4() for lep in filter(self.elSel, electrons): mht += lep.p4() goodjet = [0 for i in xrange(njets)] for i, j in enumerate(jets): if not self.jetSel(j): continue if j.muonIdx1 != -1 and j.muonIdx1 < njets: if self.muSel(muons[j.muonIdx1]): continue # prefer the muon if j.muonIdx2 != -1 and j.muonIdx2 < njets: if self.muSel(muons[j.muonIdx2]): continue # prefer the muon if j.electronIdx1 != -1 and j.electronIdx1 < njets: if self.elSel(electrons[j.electronIdx1]): continue # prefer the electron if j.electronIdx2 != -1 and j.electronIdx2 < njets: if self.elSel(electrons[j.electronIdx2]): continue # prefer the electron goodjet[i] = 1 mht += j.p4() self.out.fillBranch("MHT_pt", mht.Pt()) self.out.fillBranch("MHT_phi", -mht.Phi()) # note the minus self.out.fillBranch("Jet_mhtCleaning", goodjet) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" #print 'new event\n====================================' if not event.isData: ##leps = Collection(event, "LepGood") jets = Collection(event, "Jet") jfwd = Collection(event, "JetFwd") effs = [] for j in jets: etabin = max( 1, min(self.eff2d.GetNbinsX(), self.eff2d.GetXaxis().FindFixBin(abs(j.eta)))) ptbin = max( 1, min(self.eff2d.GetNbinsY(), self.eff2d.GetYaxis().FindFixBin(j.pt))) eff = self.eff2d.GetBinContent(etabin, ptbin) effs.append(eff) for j in jfwd: etabin = max( 1, min(self.eff2d.GetNbinsX(), self.eff2d.GetXaxis().FindFixBin(abs(j.eta)))) ptbin = max( 1, min(self.eff2d.GetNbinsY(), self.eff2d.GetYaxis().FindFixBin(j.pt))) eff = self.eff2d.GetBinContent(etabin, ptbin) effs.append(eff) if not len(effs): sf = 1. elif len(effs) == 1: sf = (1. - effs[0]) elif len(effs) >= 2: effs = sorted(effs) effs = effs[:2] sf = (1. - effs[0]) * (1. - effs[1]) else: sf = 1. ## Output self.out.fillBranch('jetsPrefireSF', sf) return True
def getVisibleV(self,event): """ tries to reconstruct a Z from the selected leptons for a W only the leading lepton is returned """ lepColl = Collection(event, "LepGood") leps=[] zCand=None nl=len(lepColl) for i in xrange(0,nl): l=lepColl[i] leps.append( l.p4() ) #check if a Z candidate can be formed for j in xrange(0,i): if abs(lepColl[i].pdgId) != abs(lepColl[j].pdgId) : continue ll=leps[i]+leps[j] if abs(ll.M()-self.llMassWindow[0])>self.llMassWindow[1] : continue zCand=(i,j) break #build the visible V from what has been found visibleV=VisibleVectorBoson(selLeptons=[leps[0]]) if len(leps)>0 else None if zCand: visibleV=VisibleVectorBoson(selLeptons=[leps[zCand[0]],leps[zCand[1]]]) return visibleV
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = Collection(event, "LepGood") calPt_step1 = [] calPt = [] for l in leps: if abs(l.pdgId)==13: # implemented only for electrons if event.isData: scale = self._rochester.kScaleDT(l.charge, l.pt, l.eta, l.phi) calPt_step1.append(scale) calPt.append(l.pt * scale) else: ## ATTENTION. THE NTRK IS RANDOMLY CHOSEN FROM A HISTOGRAM DISTRIBUTED LIKE THE SIGNAL MC ## tmp_nlayers = int(self._nLayersHist.GetRandom()) scale = self._rochester.kSpreadMC(l.charge, l.pt, l.eta, l.phi, l.mcPt, 0, 0) calPt_step1.append(scale) calPt.append(l.pt * scale ) else: if event.isData: scale = self._worker.ScaleCorrection(event.run,abs(l.etaSc)<1.479,l.r9,abs(l.eta),l.pt) calPt_step1.append(l.pt * scale) calPt.append(l.pt * scale * self.residualScale(l.pt,l.eta,event.isData)) else: smear = self._worker.getSmearingSigma(event.run,abs(l.etaSc)<1.479,l.r9,abs(l.eta),l.pt,0.,0.) corr = 1.0 + smear * self.gauss() calPt_step1.append(l.pt * corr) calPt.append(l.pt * corr) self.out.fillBranch("LepGood_calPt_step1", calPt_step1) self.out.fillBranch("LepGood_calPt", calPt) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = Collection(event, "LepGood") calPt_step1 = [] calPt = [] for l in leps: if abs(l.pdgId) != 11: # implemented only for electrons calPt.append(-999.) calPt_step1.append(-999.) else: if event.isData: scale = self._worker.ScaleCorrection( event.run, abs(l.etaSc) < 1.479, l.r9, abs(l.eta), l.pt) calPt_step1.append(l.pt * scale) calPt.append(l.pt * scale * self.residualScale(l.pt, l.eta, event.isData)) else: smear = self._worker.getSmearingSigma( event.run, abs(l.etaSc) < 1.479, l.r9, abs(l.eta), l.pt, 0., 0.) corr = 1.0 + smear * self.gauss() calPt_step1.append(l.pt * corr) calPt.append(l.pt * corr) self.out.fillBranch("LepGood_calPt_step1", calPt_step1) self.out.fillBranch("LepGood_calPt", calPt) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = filter(self.lepSel, Collection(event, "LepGood")) jets = filter(self.jetSel, Collection(event, "Jet")) jets.sort(key = self.jetSort, reverse=True) ret = {} for V in self.vars: ret[V] = [] for lep in leps: lep.awayJet = None for lep in leps: for jet in jets: if self.pairSel(lep,jet): lep.awayJet = jet break for V in self.vars: ret[V].append(getattr(lep.awayJet,V) if lep.awayJet else 0) for V in self.vars: self.out.fillBranch("LepGood_awayJet_"+V,ret[V]) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = Collection(event, "LepGood") sf = [] for l in leps: if event.isData: sf.append(1.) else: worker = self._worker_el if abs(l.pdgId)==11 else self._worker_mu sf.append(worker.getSF(l.pdgId,l.pt,l.eta)) self.out.fillBranch("LepGood_effSF", sf) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" jets = Collection(event, "Jet") for u, branchname in self.uncerts: uworker = self.factorizedUncertainties[u] jetUn = [] for j in jets: uworker.setJetEta(j.eta) uworker.setJetPt(j.pt) jetUn.append(uworker.getUncertainty(True)) self.out.fillBranch(branchname, jetUn) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = Collection(event, "LepGood") sf = [] for l in leps: if event.isData or abs(l.pdgId)!=11: sf.append(1.) else: if self.dim == 2: wgt = self._worker.getWeight(l.pt,l.eta) sf.append(wgt if wgt>0 else 1.) else: sf.append(self._worker.getWeight(getattr(l,self.var))) self.out.fillBranch("LepGood_trgSF", sf) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" coll = [Collection(event, x) for x in self.input] objects = [(coll[j][i], j, i) for j in xrange(self.nInputs) for i in xrange(len(coll[j]))] if self.selector: objects = filter(lambda (obj, j, i): self.selector[j](obj), objects) objects.sort(key=self.sortkey, reverse=self.reverse) if self.maxObjects: objects = objects[:self.maxObjects] for bridx, br in enumerate(self.brlist_all): out = [] for obj, j, i in objects: out.append(getattr(obj, br) if self.is_there[bridx][j] else 0) self.out.fillBranch("%s_%s" % (self.output, br), out) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" ret={} jets = Collection(event,self.jetCollection) isDataEvent = event.isData for V in self.vars: branch = getattr(self, "JetDummy_"+V) ret[self.jetCollection+self.label+"_"+V] = [getattr(j,V) for j in jets] if event._tree._ttreereaderversion > self._ttreereaderversion: # do this check at every event, as other modules might have read further branches self.initReaders(event._tree) # do NOT access other branches in python between the check/call to initReaders and the call to C++ worker code ## Algo cleanJets = self._worker.run() ## Output self.out.fillBranch('n'+self.jetCollection+self.label, len(cleanJets)) for V in self.vars: self.out.fillBranch(self.jetCollection+self.label+"_"+V, [ ret[self.jetCollection+self.label+"_"+V][j] for j in cleanJets ]) if self.saveJetPrefireSF: if isDataEvent: sf = 1.0 else: effs = [] for j in cleanJets: absjeta = abs(ret[self.jetCollection+self.label+"_eta"][j]) jpt = ret[self.jetCollection+self.label+"_pt"][j] # map arrives up to 3.5, and jets above that cannot prefire (even above 3.0, but a jet spread energy in a large cone, so the map is not empty between 3.0 and 3.5) # jet with pt > 30 do not prefire significantly as well if absjeta < 3.5 and jpt > 30.0: etabin = max(1, min(self.eff2d.GetNbinsX(),self.eff2d.GetXaxis().FindFixBin(absjeta))) ptbin = max(1, min(self.eff2d.GetNbinsY(),self.eff2d.GetYaxis().FindFixBin(jpt))) eff = self.eff2d.GetBinContent(etabin, ptbin) effs.append(eff) if not len(effs): sf = 1. elif len(effs) == 1: sf = (1.-effs[0]) elif len(effs) >= 2: effs = sorted(effs) effs = effs [:2] sf = 1.0 - (effs[0] + effs[1] - effs[0]*effs[1]) # SF = 1-p, p=probability that at least one jet prefires (let's stop at the first 2 with larger prefiring probability) self.out.fillBranch("jetPrefireSF_"+self.jetCollection+self.label, sf) # end of --> if self.saveJetPrefireSF: return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" ret = {} jets = Collection(event, "Jet") for V in self.vars: branch = getattr(self, "Jet_" + V) ret["Jet" + self.label + "_" + V] = [getattr(j, V) for j in jets] if event._tree._ttreereaderversion > self._ttreereaderversion: # do this check at every event, as other modules might have read further branches self.initReaders(event._tree) # do NOT access other branches in python between the check/call to initReaders and the call to C++ worker code ## Algo cleanJets = self._worker.run() ## Output self.out.fillBranch('nJet' + self.label, len(cleanJets)) for V in self.vars: self.out.fillBranch( "Jet" + self.label + "_" + V, [ret["Jet" + self.label + "_" + V][j] for j in cleanJets]) return True
def getRecoLevelVectorBoson(self,event): """tries to reconstruct a W or a Z from the selected leptons""" lepColl = Collection(event, "LepGood") if len(lepColl)==0: return None nuSum=ROOT.TLorentzVector(0,0,0,0) V=SimpleVBoson(legs=[lepColl[0].p4(),nuSum],pdgId=24) #apply trigger+offline selection cuts #FIXME: for now it's bound to muon final states passTrigger=True if event.HLT_BIT_HLT_IsoMu24_v==0 and event.HLT_BIT_HLT_IsoTkMu24_v==0: passTrigger=False passKin=True if lepColl[0].pt<25 or abs(lepColl[0].eta)>2.5: passKin=False passId = True if lepColl[0].tightId==0 or lepColl[0].relIso03>0.05: passId=False #check if a Z can be constructed instead try: candZ=SimpleVBoson(legs=[lepColl[0].p4(),lepColl[1].p4()],pdgId=23) if abs(lepColl[0].pdgId)==abs(lepColl[1].pdgId): if abs(candZ.mll()-self.llMassWindow[0])<self.llMassWindow[1] : V=candZ #apply trigger+offline selection cuts #FIXME: for now it's bound to muon final states if lepColl[1].pt<20 or abs(lepColl[1].eta)>2.5: passKin=False if lepColl[1].tightId==0 or lepColl[1].relIso03>0.05: passId=False except: pass #if not passing the cuts return None passSel=True if (passTrigger and passKin and passId) else False if not passSel: return None return V
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = Collection(event, "LepGood") iso = [] customId = [] for l in leps: if abs(l.pdgId)!=11: # implemented only for electrons iso.append(-1000) customId.append(1) else: eA = self._worker.getEffectiveArea(abs(l.eta)) rho = getattr(event,self.rho) # approximation, since we don't have the three components of the isolation # should be chad + max(0.0, nhad + pho - rho*eA) iso.append((l.relIso04*l.pt - rho*eA)/l.pt) # print "eta=%f,pt=%f,eA=%f,rho=%f,reliso=%f,relisocorr=%f" % (l.eta,l.pt,eA,rho,l.relIso04,(l.relIso04*l.pt - rho*eA)/l.pt) wp = 'loose' if abs(l.etaSc)<1.479 else 'medium' customId.append(self.passCustomIso2016(l,iso[-1]) and self.passIDnoIso2016(l,wp)) self.out.fillBranch("LepGood_relIso04EA", iso) self.out.fillBranch("LepGood_customId", customId) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = Collection(event, "LepGood") sf_1 = [] sf_2 = [] sf_3 = [] sf_1_err = [] sf_2_err = [] sf_3_err = [] for l in leps: if event.isData: sf_1.append(1.) sf_2.append(1.) sf_3.append(1.) sf_1_err.append(0.) sf_2_err.append(0.) sf_3_err.append(0.) else: if abs(l.pdgId)==11: sf_1.append(float(self.sf1_manager_el.getSF(l.pt,l.eta))) sf_2.append(float(self.sf2_manager_el.getSF(l.pt,l.eta))) sf_3.append(float(self.sf3_manager_el.getSF(l.pt,l.eta))) sf_1_err.append(float(self.sf1_manager_el.getSF_err(l.pt,l.eta))) sf_2_err.append(float(self.sf2_manager_el.getSF_err(l.pt,l.eta))) sf_3_err.append(float(self.sf3_manager_el.getSF_err(l.pt,l.eta))) else: sf_1.append( float(self.sf1_manager_mu.getSF(l.pt,l.eta))) sf_2.append( float(self.sf2_manager_mu.getSF(l.pt,l.eta))) sf_3.append( float(self.sf3_manager_mu.getSF(l.pt,l.eta))) sf_1_err.append(float(self.sf1_manager_mu.getSF_err(l.pt,l.eta))) sf_2_err.append(float(self.sf2_manager_mu.getSF_err(l.pt,l.eta))) sf_3_err.append(float(self.sf3_manager_mu.getSF_err(l.pt,l.eta))) self.out.fillBranch("LepGood_SF1", sf_1) self.out.fillBranch("LepGood_SF2", sf_2) self.out.fillBranch("LepGood_SF3", sf_3) self.out.fillBranch("LepGood_SF1_err", sf_1_err) self.out.fillBranch("LepGood_SF2_err", sf_2_err) self.out.fillBranch("LepGood_SF3_err", sf_3_err) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = Collection(event, "LepGood") if self.syst: kalPtUnc = {} ## holds the uncertainties (self._N keys) for idir in ['Up', 'Down']: for N in range(self._N): kalPtUnc['Err{i}{idir}'.format(i=N, idir=idir)] = [] kalPtUnc['ClosureErr{idir}'.format(idir=idir)] = [] else: kalPt = [] ## holds the central corrected pt for l in leps: l_ch, l_pt, l_eta, l_phi = l.charge, l.pt, l.eta, l.phi ## not implemented for electrons ## fill the array with -99 wasting a bit of space, but not too much, since the MC is mu-only and data is singleMu if abs(l.pdgId) == 11: if self.syst: for N in range(self._N): for idir in ['Up', 'Down']: kalPtUnc['Err{i}{idir}'.format( i=N, idir=idir)].append(-99) for idir in ['Up', 'Down']: kalPtUnc['ClosureErr{idir}'.format( idir=idir)].append(-99) else: kalPt.append(-99) ## here the meaningful part on muons ## for KaMuCa there is one cov matrix for data and one for MC. Here we assume that after the diagonalization they are back uncorrelated (since they are minimized on two independent datasets) ## and we want to apply the variation on data-MC difference to MC only (as a nuisance in the fit ) ## so the ith variation is kalPt_MC_Vi = kalPt_MC + (deltaPt_MC_Vi - deltaPt_data_Vi) else: centralPtMC = self._kamucaMC.getCorrectedPt( l_pt, l_eta, l_phi, l_ch) centralPtDATA = self._kamucaDATA.getCorrectedPt( l_pt, l_eta, l_phi, l_ch) if self.syst: for idir in ['Up', 'Down']: nsigma = 1 if idir == 'Up' else -1 for N in range(self._N): self._kamucaDATA.vary(N, nsigma) self._kamucaMC.vary(N, nsigma) deltaPtMC = self._kamucaMC.getCorrectedPt( l_pt, l_eta, l_phi, l_ch) - centralPtMC deltaPtDATA = self._kamucaDATA.getCorrectedPt( l_pt, l_eta, l_phi, l_ch) - centralPtDATA kalPtUnc['Err{i}{idir}'.format( i=N, idir=idir)].append(centralPtMC + deltaPtMC - deltaPtDATA) self._kamucaMC.reset() self._kamucaDATA.reset() self._kamucaMC.varyClosure(nsigma) self._kamucaDATA.varyClosure(nsigma) deltaPtMC = self._kamucaMC.getCorrectedPt( l_pt, l_eta, l_phi, l_ch) - centralPtMC deltaPtDATA = self._kamucaDATA.getCorrectedPt( l_pt, l_eta, l_phi, l_ch) - centralPtDATA kalPtUnc['ClosureErr{idir}'.format( idir=idir)].append(centralPtMC + deltaPtMC - deltaPtDATA) else: kalPt.append( centralPtDATA if event.isData else centralPtMC) if self.syst: for err, values in kalPtUnc.iteritems(): self.out.fillBranch("LepGood_kalPt{err}".format(err=err), values) else: self.out.fillBranch("LepGood_kalPt", kalPt) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" #print 'new event\n====================================' if not event.isData: ##leps = Collection(event, "LepGood") jets = Collection(event, "Jet") jfwd = Collection(event, "JetFwd") effs = [] for j in jets: etabin = max( 1, min(self.eff2d.GetNbinsX(), self.eff2d.GetXaxis().FindFixBin(abs(j.eta)))) ptbin = max( 1, min(self.eff2d.GetNbinsY(), self.eff2d.GetYaxis().FindFixBin(j.pt))) eff = self.eff2d.GetBinContent(etabin, ptbin) effs.append(eff) for j in jfwd: etabin = max( 1, min(self.eff2d.GetNbinsX(), self.eff2d.GetXaxis().FindFixBin(abs(j.eta)))) ptbin = max( 1, min(self.eff2d.GetNbinsY(), self.eff2d.GetYaxis().FindFixBin(j.pt))) eff = self.eff2d.GetBinContent(etabin, ptbin) effs.append(eff) if not len(effs): sf = 1. elif len(effs) == 1: sf = (1. - effs[0]) elif len(effs) >= 2: effs = sorted(effs) effs = effs[:2] sf = 1.0 - ( effs[0] + effs[1] - effs[0] * effs[1] ) # SF = 1-p, p=probability that at least one jet prefires ##leps = Collection(event, "LepGood") # unfortunately we need the cleaned jets, and they are only stored in the friends, so no way to access them # jets = Collection(event, self.jetCollection) # effs = [] # for j in jets: # # map arrives up to 3.5, and jets above that cannot prefire (even above 3.0, but a jet spread energy in a large cone, so the map is not empty between 3.0 and 3.5) # # jet with pt > 30 do not prefire significantly as well # if abs(j.eta) < 3.5 and j.pt > 30.0: # etabin = max(1, min(self.eff2d.GetNbinsX(),self.eff2d.GetXaxis().FindFixBin(abs(j.eta)))) # ptbin = max(1, min(self.eff2d.GetNbinsY(),self.eff2d.GetYaxis().FindFixBin(j.pt))) # eff = self.eff2d.GetBinContent(etabin, ptbin) # effs.append(eff) # if not len(effs): # sf = 1. # elif len(effs) == 1: # sf = (1.-effs[0]) # elif len(effs) >= 2: # effs = sorted(effs) # effs = effs [:2] # sf = 1.0 - (effs[0] + effs[1] - effs[0]*effs[1]) # SF = 1-p, p=probability that at least one jet prefires # else: # sf = 1. ## Output self.out.fillBranch('jetsPrefireSF', sf) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" #nothing to do if this is data if event.isData: return True try: lhe_wgts = Collection(event, 'LHEweight') except: lhe_wgts = 0 self.genParts = Collection(event, 'GenPart') #this is a stupid check if variables are present. do this on the first gen particle makeWs = False for ip, p in enumerate(self.genParts): if ip: break if hasattr(p, 'isPromptFinalState'): makeWs = True if event._tree._ttreereaderversion > self._ttreereaderversion: # do this check at every event, as other modules might have read further branches self.initReaders(event._tree) ## check if the proper Ws can be made dressedLeptonCollection = self.getDressedLeptons(strictlyPrompt=makeWs) dressedLepton, dressedLeptonPdgId = dressedLeptonCollection[0] if len( dressedLeptonCollection) else (0, 0) (preFSRLepton, preFSRLeptonPdgId) = self.getPreFSRLepton() if makeWs else (0, 0) (neutrino, neutrinoPdgId) = self.getNeutrino() if makeWs else (0, 0) if hasattr(event, "genWeight"): self.out.fillBranch("weightGen", getattr(event, "genWeight")) self.out.fillBranch( "partonId1", getattr(event, "id1") if hasattr(event, 'id1') else -999) self.out.fillBranch( "partonId2", getattr(event, "id2") if hasattr(event, 'id2') else -999) else: self.out.fillBranch("weightGen", -999.) self.out.fillBranch("partonId1", -999) self.out.fillBranch("partonId2", -999) #always produce the dressed lepton collection if len(dressedLeptonCollection) > 0: retL = {} leptonsToTake = range( 0, 1 if makeWs else len(dressedLeptonCollection)) retL["pt"] = [ dressedLeptonCollection[i][0].Pt() for i in leptonsToTake ] retL["eta"] = [ dressedLeptonCollection[i][0].Eta() for i in leptonsToTake ] retL["phi"] = [ dressedLeptonCollection[i][0].Phi() for i in leptonsToTake ] retL["mass"] = [ dressedLeptonCollection[i][0].M() if dressedLeptonCollection[i][0].M() >= 0. else 0. for i in leptonsToTake ] retL["pdgId"] = [ dressedLeptonCollection[i][1] for i in leptonsToTake ] self.out.fillBranch("nGenLepDressed", leptonsToTake[-1]) for V in self.vars: self.out.fillBranch("GenLepDressed_" + V, retL[V]) #W-specific if neutrino: retN = {} retN["pt"] = [neutrino.Pt()] retN["eta"] = [neutrino.Eta()] retN["phi"] = [neutrino.Phi()] retN["mass"] = [ neutrino.M() if neutrino.M() >= 0. else 0. ] ## weird protection... also already checked. but better safe than sorry retN["pdgId"] = [neutrinoPdgId] self.out.fillBranch("nGenPromptNu", 1) for V in self.vars: self.out.fillBranch("GenPromptNu_" + V, retN[V]) #self.out.fillBranch("GenPromptNu_pdgId", [pdgId for pdgId in nuPdgIds]) if dressedLepton: genw = dressedLepton + neutrino self.out.fillBranch("genw_charge", float(-1 * np.sign(dressedLeptonPdgId))) self.out.fillBranch("genw_pt", genw.Pt()) self.out.fillBranch("genw_y", genw.Rapidity()) self.out.fillBranch("genw_mass", genw.M()) kv = KinematicVars(self.beamEn) # convention for phiCS: use l- direction for W-, use neutrino for W+ (lplus, lminus) = (neutrino, dressedLepton) if dressedLeptonPdgId < 0 else ( dressedLepton, neutrino) self.out.fillBranch("genw_costcs", kv.cosThetaCS(lplus, lminus)) self.out.fillBranch("genw_phics", kv.phiCS(lplus, lminus)) self.out.fillBranch("genw_decayId", abs(neutrinoPdgId)) for imass in self.massWeights: self.out.fillBranch( "mass_{mass}".format(mass=imass), self.bwWeight(genMass=genw.M() * 1000, imass=imass)) if preFSRLepton: retP = {} retP["pt"] = [preFSRLepton.Pt()] retP["eta"] = [preFSRLepton.Eta()] retP["phi"] = [preFSRLepton.Phi()] retP["mass"] = [ preFSRLepton.M() if preFSRLepton.M() >= 0. else 0. ] retP["pdgId"] = [preFSRLeptonPdgId] self.out.fillBranch("nGenLepPreFSR", 1) for V in self.vars: self.out.fillBranch("GenLepPreFSR_" + V, retP[V]) prefsrw = preFSRLepton + neutrino self.out.fillBranch("prefsrw_charge", float(-1 * np.sign(preFSRLeptonPdgId))) self.out.fillBranch("prefsrw_pt", prefsrw.Pt()) self.out.fillBranch("prefsrw_y", prefsrw.Rapidity()) self.out.fillBranch("prefsrw_mass", prefsrw.M()) kv = KinematicVars(self.beamEn) # convention for phiCS: use l- direction for W-, use neutrino for W+ (lplus, lminus) = (neutrino, preFSRLepton) if preFSRLeptonPdgId < 0 else ( preFSRLepton, neutrino) self.out.fillBranch("prefsrw_costcs", kv.cosThetaCS(lplus, lminus)) self.out.fillBranch("prefsrw_phics", kv.phiCS(lplus, lminus)) self.out.fillBranch("prefsrw_decayId", abs(neutrinoPdgId)) for imass in self.massWeights: self.out.fillBranch( "mass_{mass}".format(mass=imass), self.bwWeight(genMass=prefsrw.M() * 1000, imass=imass)) ## remove these variables to save space #self.out.fillBranch("genw_mt" , sqrt(2*lplus.Pt()*lminus.Pt()*(1.-cos(deltaPhi(lplus.Phi(),lminus.Phi())) ))) #self.out.fillBranch("genw_eta",genw.Eta()) #self.out.fillBranch("genw_phi",genw.Phi()) #self.out.fillBranch("genw_costcm",kv.cosThetaCM(lplus,lminus)) #self.out.fillBranch("genw_cost2d",kv.cosTheta2D(genw,dressedLeptons[0])) else: ## no neutrino found! ##if not len(dressedLeptons): ## print '================================' ## print 'no dressed leptons found!' ## print 'no dressed leptons fround :lumi:evt: {a}:{b}:{c}'.format(a=getattr(event, "run"),b=getattr(event, "lumi"),c=getattr(event, "evt")) ##else: ## print '================================' ## print 'no neutrinos found, in run:lumi:evt: {a}:{b}:{c}'.format(a=getattr(event, "run"),b=getattr(event, "lumi"),c=getattr(event, "evt")) for V in self.genwvars: self.out.fillBranch("genw_" + V, -999) self.out.fillBranch("prefsrw_" + V, -999) for imass in self.massWeights: self.out.fillBranch("mass_{mass}".format(mass=imass), 1.) if lhe_wgts: lheweights = [w.wgt for w in lhe_wgts] # not there anymore lhewgtIDs = [w.id for w in lhe_wgts] # not there anymore if not lhewgtIDs[self.pdfWeightOffset]%10 ==1: # not there anymore print 'ERROR/WARNING: the LHE weight with offset {n} does not seem to be the first replica!!!!'.format(n=self.pdfWeightOffset) hessWgt = self.mcRep2Hess( lheweights ) ## give all the lhe weights. the 0th entry is the nominal one for N in range(1, self.nHessianWeights + 1): self.out.fillBranch("hessWgt" + str(N), hessWgt[N - 1]) qcd0Wgt = lheweights[self.qcdScaleWgtIdx()] for ii, idir in enumerate(['Up', 'Dn']): self.out.fillBranch( "qcd_muR{idir}".format(idir=idir), lheweights[self.qcdScaleWgtIdx(mur=idir)] / qcd0Wgt) self.out.fillBranch( "qcd_muF{idir}".format(idir=idir), lheweights[self.qcdScaleWgtIdx(muf=idir)] / qcd0Wgt) self.out.fillBranch( "qcd_muRmuF{idir}".format(idir=idir), lheweights[self.qcdScaleWgtIdx(mur=idir, muf=idir)] / qcd0Wgt) # only correlated variations are physical self.out.fillBranch( "qcd_alphaS{idir}".format(idir=idir), lheweights[-1 - ii] / lheweights[0] ) # alphaS is at the end of the pdf variations. 0.119 is last, 0.117 next-to-last return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" #nothing to do if this is data if event.isData: return True try: lhe_wgts = Collection(event, 'LHEweight') except: lhe_wgts = 0 self.genParts = Collection(event, 'GenPart') #this is a stupid check if variables are present. do this on the first gen particle makeBosons = False for ip, p in enumerate(self.genParts): if ip: break if hasattr(p, 'isPromptFinalState'): makeBosons = True if event._tree._ttreereaderversion > self._ttreereaderversion: # do this check at every event, as other modules might have read further branches self.initReaders(event._tree) ## check if the proper Ws can be made bareLeptonCollection = self.getBareLeptons(strictlyPrompt=makeBosons) dressedLeptonCollection = self.getDressedLeptons( bareLeptonCollection, strictlyPrompt=makeBosons) dressedLepton, dressedLeptonPdgId, dressedLeptonVertexZ = dressedLeptonCollection[ 0] if len(dressedLeptonCollection) else (0, 0, 0) bareLepton, bareLeptonPdgId, bareLeptonVertexZ = bareLeptonCollection[ 0] if len(bareLeptonCollection) else (0, 0, 0) #(preFSRLepton , preFSRLeptonPdgId ) = self.getPreFSRLepton() if makeBosons else (0,0) (neutrino, neutrinoPdgId) = self.getNeutrino() if makeBosons else (0, 0) ## new to work also for Z if not self.noSavePreFSR: preFSRLeptonsAndPdgIds = self.getPreFSRLepton( ) if makeBosons else [] # let's save all preFSR leptons. If one wants to save space then it should be better to # save two opposite sign leptons rather than the leading 2 # ## take the two hardest preFSR leptons if there are 4, which happens with photos #if len(preFSRLeptonsAndPdgIds) == 4: # preFSRLeptonsAndPdgIds = preFSRLeptonsAndPdgIds[:2] ## keep commented to save all particles # # if len(dressedLeptonCollection) == 4: # dressedLeptonCollection = dressedLeptonCollection[:2] # ## ================================= #always produce the dressed lepton collection if len(dressedLeptonCollection): self.out.fillBranch("nGenLepDressed", len(dressedLeptonCollection)) retL = {} #leptonsToTake = range(0,1 if makeBosons else len(dressedLeptonCollection)) retL["pt"] = [leppy[0].Pt() for leppy in dressedLeptonCollection] retL["eta"] = [leppy[0].Eta() for leppy in dressedLeptonCollection] retL["phi"] = [leppy[0].Phi() for leppy in dressedLeptonCollection] retL["pdgId"] = [leppy[1] for leppy in dressedLeptonCollection] retL["mass"] = [leppy[0].M() if leppy[0].M() >= 0. else 0.] retL["vertexZ"] = [leppy[2] for leppy in dressedLeptonCollection] retL["fsrDR"] = [] retL["fsrPt"] = [] for leppy in dressedLeptonCollection: photonsFSR = self.getFSRPhotons(leppy[0], leppy[1]) retL["fsrDR"].append(photonsFSR[0].DeltaR(leppy[0]) if len(photonsFSR) > 0 else -1) retL["fsrPt"].append( photonsFSR[0].Pt() if len(photonsFSR) > 0 else -1) for V in self.vars: self.out.fillBranch("GenLepDressed_" + V, retL[V]) if self.saveVertexZ: self.out.fillBranch("GenLepDressed_vertexZ", retL["vertexZ"]) #always produce the bare lepton collection if len(bareLeptonCollection) > 0: retB = {} #leptonsToTake = range(0,1 if makeBosons else len(bareLeptonCollection)) leptonsToTake = range(0, len(bareLeptonCollection)) retB["pt"] = [ bareLeptonCollection[i][0].Pt() for i in leptonsToTake ] retB["eta"] = [ bareLeptonCollection[i][0].Eta() for i in leptonsToTake ] retB["phi"] = [ bareLeptonCollection[i][0].Phi() for i in leptonsToTake ] retB["mass"] = [ bareLeptonCollection[i][0].M() if dressedLeptonCollection[i][0].M() >= 0. else 0. for i in leptonsToTake ] retB["pdgId"] = [bareLeptonCollection[i][1] for i in leptonsToTake] #retB["vertexZ"] = [bareLeptonCollection[i][2] for i in leptonsToTake ] retB["fsrDR"] = [] retB["fsrPt"] = [] for i in leptonsToTake: photonsFSR = self.getFSRPhotons(bareLeptonCollection[i][0], bareLeptonCollection[i][1]) retB["fsrDR"].append(photonsFSR[0].DeltaR( bareLeptonCollection[i][0]) if len(photonsFSR) > 0 else -1) retB["fsrPt"].append( photonsFSR[0].Pt() if len(photonsFSR) > 0 else -1) self.out.fillBranch("nGenLepBare", leptonsToTake[-1]) for V in self.vars: self.out.fillBranch("GenLepBare_" + V, retB[V]) if self.saveVertexZ: self.out.fillBranch("GenLepBare_vertexZ", retL["vertexZ"]) #W-specific if neutrino: retN = {} retN["pt"] = [neutrino.Pt()] retN["eta"] = [neutrino.Eta()] retN["phi"] = [neutrino.Phi()] retN["mass"] = [ neutrino.M() if neutrino.M() >= 0. else 0. ] ## weird protection... also already checked. but better safe than sorry retN["pdgId"] = [neutrinoPdgId] retN["fsrDR"] = [-1] retN["fsrPt"] = [-1] self.out.fillBranch("nGenPromptNu", 1) for V in self.vars: self.out.fillBranch("GenPromptNu_" + V, retN[V]) #self.out.fillBranch("GenPromptNu_pdgId", [pdgId for pdgId in nuPdgIds]) if not self.noSavePreFSR: if len(preFSRLeptonsAndPdgIds): self.out.fillBranch("nGenLepPreFSR", len(preFSRLeptonsAndPdgIds)) retP = {} retP["pt"] = [ leppy[0].Pt() for leppy in preFSRLeptonsAndPdgIds ] retP["eta"] = [ leppy[0].Eta() for leppy in preFSRLeptonsAndPdgIds ] retP["phi"] = [ leppy[0].Phi() for leppy in preFSRLeptonsAndPdgIds ] retP["pdgId"] = [leppy[1] for leppy in preFSRLeptonsAndPdgIds] retP["mass"] = [ leppy[0].M() if leppy[0].M() >= 0. else 0. for leppy in preFSRLeptonsAndPdgIds ] retP["fsrDR"] = [] retP["fsrPt"] = [] for leppy in preFSRLeptonsAndPdgIds: photonsFSR = self.getFSRPhotons(leppy[0], leppy[1]) retP["fsrDR"].append(photonsFSR[0].DeltaR(leppy[0]) if len(photonsFSR) > 0 else -1) retP["fsrPt"].append( photonsFSR[0].Pt() if len(photonsFSR) > 0 else -1) for V in self.vars: self.out.fillBranch("GenLepPreFSR_" + V, retP[V]) # this part is to be revisited if I change the number of saved GenLepDressed or bare # there should be 2 or 4 (for photos), when there are 4 the first 2 are saved # but I might want to save all #if len(preFSRLeptonsAndPdgIds) == 2 or (len(preFSRLeptonsAndPdgIds) == 1 and neutrino): if not neutrino: ## these are Zs isWBoson = False prefsrw = preFSRLeptonsAndPdgIds[0][ 0] + preFSRLeptonsAndPdgIds[1][0] self.out.fillBranch("prefsrw_charge", 0) l1, l1pdg, l2 = preFSRLeptonsAndPdgIds[0][ 0], preFSRLeptonsAndPdgIds[0][ 1], preFSRLeptonsAndPdgIds[1][0] # convention for phiCS: use l- direction for W-, use neutrino for W+ (lplus, lminus) = (l2, l1) if l1pdg < 0 else (l1, l2) self.out.fillBranch("prefsrw_decayId", abs(l1pdg)) else: ## these are Ws isWBoson = True prefsrw = preFSRLeptonsAndPdgIds[0][0] + neutrino self.out.fillBranch( "prefsrw_charge", float(-1 * np.sign(preFSRLeptonsAndPdgIds[0][1]))) l1, l1pdg = preFSRLeptonsAndPdgIds[0][ 0], preFSRLeptonsAndPdgIds[0][1] # convention for phiCS: use l- direction for W-, use neutrino for W+ (lplus, lminus) = (neutrino, l1) if l1pdg < 0 else (l1, neutrino) self.out.fillBranch("prefsrw_decayId", abs(neutrinoPdgId)) self.out.fillBranch("prefsrw_pt", prefsrw.Pt()) self.out.fillBranch("prefsrw_y", prefsrw.Rapidity()) self.out.fillBranch("prefsrw_mass", prefsrw.M()) kv = KinematicVars(self.beamEn) self.out.fillBranch("prefsrw_costcs", kv.cosThetaCS(lplus, lminus)) self.out.fillBranch("prefsrw_phics", kv.phiCS(lplus, lminus)) for imass in self.massBWWeights: masssign = 'm' if imass < 0 else 'p' if imass > 0 else '' self.out.fillBranch( "mass_{s}{mass}".format(s=masssign, mass=abs(imass)), self.bwWeight(genMass=prefsrw.M() * 1000, imass=imass, isW=isWBoson)) #if len(dressedLeptonCollection) == 2 or (len(dressedLeptonCollection) == 1 and neutrino): if len(dressedLeptonCollection): if not neutrino: ## these are Zs isWBoson = False genw = dressedLeptonCollection[0][0] + dressedLeptonCollection[ 1][0] self.out.fillBranch("genw_charge", 0) l1, l1pdg, l2 = dressedLeptonCollection[0][ 0], dressedLeptonCollection[0][1], dressedLeptonCollection[ 1][0] # convention for phiCS: use l- direction for W-, use neutrino for W+ (lplus, lminus) = (l2, l1) if l1pdg < 0 else (l1, l2) self.out.fillBranch("genw_decayId", abs(l1pdg)) else: ## these are Ws isWBoson = True genw = dressedLeptonCollection[0][0] + neutrino self.out.fillBranch( "genw_charge", float(-1 * np.sign(dressedLeptonCollection[0][1]))) l1, l1pdg = dressedLeptonCollection[0][ 0], dressedLeptonCollection[0][1] # convention for phiCS: use l- direction for W-, use neutrino for W+ (lplus, lminus) = (neutrino, l1) if l1pdg < 0 else (l1, neutrino) self.out.fillBranch("genw_decayId", abs(neutrinoPdgId)) self.out.fillBranch("genw_pt", genw.Pt()) self.out.fillBranch("genw_y", genw.Rapidity()) self.out.fillBranch("genw_mass", genw.M()) kv = KinematicVars(self.beamEn) self.out.fillBranch("genw_costcs", kv.cosThetaCS(lplus, lminus)) self.out.fillBranch("genw_phics", kv.phiCS(lplus, lminus)) ## filling mass weights must be done on preFSR only #for imass in self.massBWWeights: # masssign = 'm' if imass < 0 else 'p' if imass > 0 else '' # self.out.fillBranch("mass_{s}{mass}".format(s=masssign,mass=abs(imass)), self.bwWeight(genMass=genw.M()*1000,imass=imass,isW=isWBoson)) ## remove these variables to save space #self.out.fillBranch("genw_mt" , sqrt(2*lplus.Pt()*lminus.Pt()*(1.-cos(deltaPhi(lplus.Phi(),lminus.Phi())) ))) #self.out.fillBranch("genw_eta",genw.Eta()) #self.out.fillBranch("genw_phi",genw.Phi()) #self.out.fillBranch("genw_costcm",kv.cosThetaCM(lplus,lminus)) #self.out.fillBranch("genw_cost2d",kv.cosTheta2D(genw,dressedLeptons[0])) else: ## no dressed lepton ##if not len(dressedLeptons): ## print '================================' ## print 'no dressed leptons found!' ## print 'no dressed leptons fround :lumi:evt: {a}:{b}:{c}'.format(a=getattr(event, "run"),b=getattr(event, "lumi"),c=getattr(event, "evt")) ##else: ## print '================================' ## print 'no neutrinos found, in run:lumi:evt: {a}:{b}:{c}'.format(a=getattr(event, "run"),b=getattr(event, "lumi"),c=getattr(event, "evt")) for V in self.genwvars: self.out.fillBranch("genw_" + V, -999) if not self.noSavePreFSR: self.out.fillBranch("prefsrw_" + V, -999) for imass in self.massBWWeights: masssign = 'm' if imass < 0 else 'p' if imass > 0 else '' self.out.fillBranch( "mass_{s}{mass}".format(s=masssign, mass=abs(imass)), 1.) if hasattr(event, "genWeight"): self.out.fillBranch( "partonId1", getattr(event, "id1") if hasattr(event, 'id1') else -999) self.out.fillBranch( "partonId2", getattr(event, "id2") if hasattr(event, 'id2') else -999) else: self.out.fillBranch("partonId1", -999) self.out.fillBranch("partonId2", -999) centralPDFWeight = 1. if lhe_wgts: lheweights = [w.wgt for w in lhe_wgts] ## set here the nominal weight for the PDF set we want to use: ## the index should be: ## 18 for NNPDF31_nnlo_hessian_pdfas ## 129 for NNPDF31_nnlo_as_0118_CMSW1_hessian_100, where: CMSW1 => No CMS W data ## 230 for NNPDF31_nnlo_as_0118_CMSW2_hessian_100, where: CMSW2 => No collider W data ## 331 for NNPDF31_nnlo_as_0118_CMSW3_hessian_100, where: CMSW3 => No CMS W,Z data ## 432 for NNPDF31_nnlo_as_0118_CMSW4_hessian_100, where: CMSW4 => No collider W,Z data ## 533 for CT14nnlo ATTENTION, number of hessianWeights is: 29 ## 592 for MMHT2014nnlo68cl ATTENTION, number of hessianWeights is: 51, alphaS separate ## 646 for ABMP16_5_nnlo ATTENTION, number of hessianWeights is: 30 ## 676 for HERAPDF20_NNLO_EIG ATTENTION, number of hessianWeights is: 29 ## 705 for HERAPDF20_NNLO_VAR ATTENTION, number of hessianWeights is: 14, alphaS separate centralPDFIndex = 432 ## for CMSW4 centralPDFWeight = lheweights[centralPDFIndex] ## 423 for CMSW4 ## the PDF variations are saved as ratios w/r/t the nominal weight of the selected sample ## i.e. running a template with pdf6 up will be pdfCentralWgt * hessWgt6, ## while the nominal template will be just pdfCentralWgt for N in range(1, self.nHessianWeights + 1): self.out.fillBranch( "hessWgt" + str(N), lheweights[centralPDFIndex + N] / centralPDFWeight if centralPDFWeight else 0.) qcd0Wgt = lheweights[self.qcdScaleWgtIdx()] for ii, idir in enumerate(['Up', 'Dn']): self.out.fillBranch( "qcd_muR{idir}".format(idir=idir), lheweights[self.qcdScaleWgtIdx(mur=idir)] / qcd0Wgt) self.out.fillBranch( "qcd_muF{idir}".format(idir=idir), lheweights[self.qcdScaleWgtIdx(muf=idir)] / qcd0Wgt) self.out.fillBranch( "qcd_muRmuF{idir}".format(idir=idir), lheweights[self.qcdScaleWgtIdx(mur=idir, muf=idir)] / qcd0Wgt) # only correlated variations are physical ## alphaS now different in new MC. CMSW4 does not have a alphaS variation, so taking the one of the nominal PDF set self.out.fillBranch( "qcd_alphaS{idir}".format(idir=idir), lheweights[110 + ii] ) ## 110 is alphaS-up of nominal pdf set, 111 is alphaS-down of nominal pdf set if len(lhe_wgts) > (self.massWeightsIdx + len(self.massWeights)): for i, m in enumerate(self.massWeights): self.out.fillBranch( "mass_shift{0}MeV{1}".format( *self.massShiftAndType(m)), lheweights[i + self.massWeightsIdx] / qcd0Wgt) ## save the central PDF weight that is either 1. or set in the previous block of code self.out.fillBranch("pdfCentralWgt", centralPDFWeight) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = Collection(event, "LepGood") sf_1 = [] sf_2 = [] sf_3 = [] sf_4 = [] sf_1_err = [] sf_2_err = [] sf_3_err = [] sf_4_err = [] for l in leps: if event.isData: sf_1.append(1.) sf_2.append(1.) sf_3.append(1.) sf_4.append(1.) sf_1_err.append(0.) sf_2_err.append(0.) sf_3_err.append(0.) sf_4_err.append(0.) else: if abs(l.pdgId) == 11: sf1_manager_el = self.sf1_manager_el_e if abs( l.eta) > 1.566 else self.sf1_manager_el_b sf2_manager_el = self.sf2_manager_el sf3_manager_el = self.sf3_manager_el_e if abs( l.eta) > 1.566 else self.sf3_manager_el_b sf4_manager_el = self.sf4_manager_el sf_1.append(float(sf1_manager_el.getSF(l.pt, l.eta))) sf_2.append(float(sf2_manager_el.getSF(l.pt, l.eta))) sf_3.append(float(sf3_manager_el.getSF(l.pt, l.eta))) sf_4.append(float(sf4_manager_el.getSF(l.pt, l.eta))) sf_1_err.append( float(sf1_manager_el.getSF_err(l.pt, l.eta))) sf_2_err.append( float(sf2_manager_el.getSF_err(l.pt, l.eta))) sf_3_err.append( float(sf3_manager_el.getSF_err(l.pt, l.eta))) sf_4_err.append(0) else: ## muon trigger SF now split by charge if l.charge > 0: sf_1.append( float(self.sf1_manager_mu_plus.getSF(l.pt, l.eta))) sf_1_err.append( float( self.sf1_manager_mu_plus.getSF_err( l.pt, l.eta))) else: sf_1.append( float(self.sf1_manager_mu_minus.getSF(l.pt, l.eta))) sf_1_err.append( float( self.sf1_manager_mu_minus.getSF_err( l.pt, l.eta))) sf_2.append(float(self.sf2_manager_mu.getSF(l.pt, l.eta))) sf_3.append( 1.) #float(self.sf3_manager_mu.getSF(l.pt,l.eta))) sf_4.append(1.) sf_2_err.append( float(self.sf2_manager_mu.getSF_err(l.pt, l.eta))) sf_3_err.append( 0.) #float(self.sf3_manager_mu.getSF_err(l.pt,l.eta))) sf_4_err.append(0.) self.out.fillBranch("LepGood_SF1", sf_1) self.out.fillBranch("LepGood_SF2", sf_2) self.out.fillBranch("LepGood_SF3", sf_3) self.out.fillBranch("LepGood_SF4", sf_4) self.out.fillBranch("LepGood_SF1_err", sf_1_err) self.out.fillBranch("LepGood_SF2_err", sf_2_err) self.out.fillBranch("LepGood_SF3_err", sf_3_err) self.out.fillBranch("LepGood_SF4_err", sf_4_err) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leps = Collection(event, "LepGood") rocPt_step1 = [] rocPt = [] rocPt_stat = {} for istat in range(100): rocPt_stat[istat] = [] #rocPt_syst = {} # not now for l in leps: l_ch, l_pt, l_eta, l_phi = l.charge, l.pt, l.eta, l.phi if abs(l.pdgId) == 13: # implemented only for electrons if event.isData: scale = self._rochester.kScaleDT(l_ch, l_pt, l_eta, l_phi, 0, 0) rocPt_step1.append(scale) rocPt.append(l.pt * scale) if self.saveRochesterStatVariations: for istat in range(100): statvar = self._rochester.kScaleDT( l_ch, l_pt, l_eta, l_phi, 1, istat) rocPt_stat[istat].append(l.pt * statvar) else: l_gpt = l.mcPt if l_gpt: scale = self._rochester.kSpreadMC( l_ch, l_pt, l_eta, l_phi, l_gpt, 0, 0) if self.saveRochesterStatVariations: for istat in range(100): statvar = self._rochester.kSpreadMC( l_ch, l_pt, l_eta, l_phi, l_gpt, 1, istat) rocPt_stat[istat].append(l.pt * statvar) else: ## ATTENTION. THE NTRK IS RANDOMLY CHOSEN FROM A HISTOGRAM DISTRIBUTED LIKE THE SIGNAL MC tmp_nlayers = int(self._nLayersHist.GetRandom()) scale = self._rochester.kSmearMC( l_ch, l_pt, l_eta, l_phi, tmp_nlayers, ROOT.gRandom.Rndm(), 0, 0) if self.saveRochesterStatVariations: for istat in range(100): statvar = self._rochester.kSmearMC( l_ch, l_pt, l_eta, l_phi, tmp_nlayers, ROOT.gRandom.Rndm(), 1, istat) rocPt_stat[istat].append(l.pt * statvar) rocPt_step1.append(scale) rocPt.append(l.pt * scale) else: if self.skipElectron: rocPt_step1.append(-999.9) rocPt.append(-999.9) if self.saveRochesterStatVariations: for istat in range(100): rocPt_stat[istat].append(-999.9) else: if event.isData: scale = self._worker.ScaleCorrection( event.run, abs(l.etaSc) < 1.479, l.r9, abs(l.eta), l.pt) rocPt_step1.append(l.pt * scale) rocPt.append( l.pt * scale * self.residualScale(l.pt, l.eta, event.isData)) else: smear = self._worker.getSmearingSigma( event.run, abs(l.etaSc) < 1.479, l.r9, abs(l.eta), l.pt, 0., 0.) corr = 1.0 + smear * self.gauss() rocPt_step1.append(l.pt * corr) rocPt.append(l.pt * corr) # same dummy for both data and MC if self.saveRochesterStatVariations: for i in range(100): rocPt_stat[istat].append(-999.9) self.out.fillBranch("LepGood_rocPt_step1", rocPt_step1) self.out.fillBranch("LepGood_rocPt", rocPt) if self.saveRochesterStatVariations: for istat in range(100): self.out.fillBranch("LepGood_rocPt_stat%d" % istat, rocPt_stat[istat]) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" lhe_wgts = Collection(event, "LHEweight") if event._tree._ttreereaderversion > self._ttreereaderversion: # do this check at every event, as other modules might have read further branches self.initReaders(event._tree) # do NOT access other branches in python between the check/call to initReaders and the call to C++ worker code ## Algo self._worker.run() dressedLeptons = self._worker.dressedLeptons() neutrinos = self._worker.promptNeutrinos() lepPdgIds = self._worker.dressedLeptonsPdgId() nuPdgIds = self._worker.promptNeutrinosPdgId() gammaMaxDR = self._worker.gammaMaxDR() gammaRelPtOutside = self._worker.gammaRelPtOutside() self.out.fillBranch("gammaMaxDR", gammaMaxDR) self.out.fillBranch("gammaRelPtOutside", gammaRelPtOutside) #nothing to do if this is data if event.isData: return True if hasattr(event, "genWeight"): self.out.fillBranch("weightGen", getattr(event, "genWeight")) self.out.fillBranch("partonId1", getattr(event, "id1")) self.out.fillBranch("partonId2", getattr(event, "id2")) else: self.out.fillBranch("weightGen", -999.) self.out.fillBranch("partonId1", -999) self.out.fillBranch("partonId2", -999) retL = {} retL["pt"] = [dl.Pt() for dl in dressedLeptons] retL["eta"] = [dl.Eta() for dl in dressedLeptons] retL["phi"] = [dl.Phi() for dl in dressedLeptons] retL["mass"] = [dl.M() for dl in dressedLeptons] retL["pdgId"] = [pdgId for pdgId in lepPdgIds] self.out.fillBranch("nGenLepDressed", len(dressedLeptons)) for V in self.vars: self.out.fillBranch("GenLepDressed_" + V, retL[V]) self.out.fillBranch("GenLepDressed_pdgId", [pdgId for pdgId in lepPdgIds]) retN = {} retN["pt"] = [nu.Pt() for nu in neutrinos] retN["eta"] = [nu.Eta() for nu in neutrinos] retN["phi"] = [nu.Phi() for nu in neutrinos] retN["mass"] = [nu.M() for nu in neutrinos] retN["pdgId"] = [pdgId for pdgId in lepPdgIds] self.out.fillBranch("nGenPromptNu", len(neutrinos)) for V in self.vars: self.out.fillBranch("GenPromptNu_" + V, retN[V]) self.out.fillBranch("GenPromptNu_pdgId", [pdgId for pdgId in nuPdgIds]) if len(dressedLeptons) and len(neutrinos): genw = dressedLeptons[0] + neutrinos[0] self.out.fillBranch("genw_charge", float(-1 * np.sign(lepPdgIds[0]))) self.out.fillBranch("genw_pt", genw.Pt()) self.out.fillBranch("genw_eta", genw.Eta()) self.out.fillBranch("genw_phi", genw.Phi()) self.out.fillBranch("genw_y", genw.Rapidity()) self.out.fillBranch("genw_mass", genw.M()) kv = KinematicVars(self.beamEn) # convention for phiCS: use l- direction for W-, use neutrino for W+ (lplus, lminus) = (neutrinos[0], dressedLeptons[0]) if lepPdgIds[0] < 0 else ( dressedLeptons[0], neutrinos[0]) self.out.fillBranch("genw_costcm", kv.cosThetaCM(lplus, lminus)) self.out.fillBranch("genw_costcs", kv.cosThetaCS(lplus, lminus)) self.out.fillBranch("genw_cost2d", kv.cosTheta2D(genw, dressedLeptons[0])) self.out.fillBranch("genw_phics", kv.phiCS(lplus, lminus)) self.out.fillBranch( "genw_mt", sqrt(2 * lplus.Pt() * lminus.Pt() * (1. - cos(deltaPhi(lplus.Phi(), lminus.Phi()))))) self.out.fillBranch("genw_decayId", abs(nuPdgIds[0])) else: ##if not len(dressedLeptons): ## print '================================' ## print 'no dressed leptons found!' ## print 'no dressed leptons fround :lumi:evt: {a}:{b}:{c}'.format(a=getattr(event, "run"),b=getattr(event, "lumi"),c=getattr(event, "evt")) ##else: ## print '================================' ## print 'no neutrinos found, in run:lumi:evt: {a}:{b}:{c}'.format(a=getattr(event, "run"),b=getattr(event, "lumi"),c=getattr(event, "evt")) for V in self.genwvars: self.out.fillBranch("genw_" + V, -999) lheweights = [w.wgt for w in lhe_wgts] lhewgtIDs = [w.id for w in lhe_wgts] if not lhewgtIDs[self.pdfWeightOffset] % 10 == 1: print 'ERROR/WARNING: the LHE weight with offset {n} does not seem to be the first replica!!!!'.format( n=self.pdfWeightOffset) hessWgt = self.mcRep2Hess( lheweights ) ## give all the lhe weights. the 0th entry is the nominal one for N in range(1, self.nHessianWeights + 1): self.out.fillBranch("hessWgt" + str(N), hessWgt[N - 1]) qcd0Wgt = lheweights[self.qcdScaleWgtIdx()] for ii, idir in enumerate(['Up', 'Dn']): self.out.fillBranch( "qcd_muR{idir}".format(idir=idir), lheweights[self.qcdScaleWgtIdx(mur=idir)] / qcd0Wgt) self.out.fillBranch( "qcd_muF{idir}".format(idir=idir), lheweights[self.qcdScaleWgtIdx(muf=idir)] / qcd0Wgt) self.out.fillBranch( "qcd_muRmuF{idir}".format(idir=idir), lheweights[self.qcdScaleWgtIdx(mur=idir, muf=idir)] / qcd0Wgt) # only correlated variations are physical self.out.fillBranch( "qcd_alphaS{idir}".format(idir=idir), lheweights[-1 - ii] / lheweights[0] ) # alphaS is at the end of the pdf variations. 0.119 is last, 0.117 next-to-last return True