def prepareEvent(self, event): logging.debug('processing event %d' % event.event) ## met selection if event.met.pt < 50.0: return False ## muon selection event._allMuons = Collection(event, "Muon") event.muons = [] for muon in event._allMuons: if muon.pt > 55 and abs(muon.eta) < 2.4 and muon.tightId and abs( muon.dxy) < 0.2 and abs(muon.dz) < 0.5: if muon.miniPFRelIso_all < 0.10: event.muons.append(muon) if len(event.muons) != 1: return False # #leptonic W pt cut event.mu = event.muons[0] event.leptonicW = event.mu.p4() + event.met.p4() if event.leptonicW.Pt() < 100.0: return False ## b-tag AK4 jet selection event.bjets = [] for j in event._allJets: if not (j.pt > 25.0 and abs(j.eta) < 2.4 and (j.jetId & 2)): continue if j.btagDeepB > self.DeepCSV_WP_M and abs( deltaPhi(j, event.muons[0])) < 2.0: event.bjets.append(j) if len(event.bjets) < 1: return False # # selection on AK8/AK15 jets event.fatjets = [] for fj in event._allFatJets: if not (fj.pt > 150 and abs(fj.eta) < 2.4 and (fj.jetId & 2)): continue if abs(deltaPhi(fj, event.muons[0])) > 2.0: event.fatjets.append(fj) if len(event.fatjets) < 1: return False ## return True if passes selection return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" ## Getting objects jets = Collection(event, "Jet") #if self.isData == False: genjets = Collection(event, "GenJet") met = Object(event, self.metBranchName) jetNearMETInd, MMJetDPhi = -1, -1 for iJ in range(1, len(jets)): if iJ > 2: continue dPhi = abs(deltaPhi(jets[iJ].phi, met.phi)) if (MMJetDPhi < 0 or dPhi < MMJetDPhi): MMJetDPhi = dPhi jetNearMETInd = iJ if jetNearMETInd < 0: return True pJ = jets[jetNearMETInd] passFilter = len(jets) > jetNearMETInd pseudoGenPT = self.addFourVec(met, pJ).Pt() MMPseudoResp = pJ.pt / pseudoGenPT if pseudoGenPT > 0 else 999 # True response info #print "isQCD: ", self.isQCD mmOut = [] #if self.isQCD == True or self.isQCDOrig == True: #if isData ==False: mmOut = self.getQCDRespTailCorrector(jets, genjets, met) #else: # mmOut = [-1, -1.0, -1] trueRespInd, trueResp = mmOut[0], mmOut[1] #print "trueResp: ", trueRespInd, trueResp trueRespFlv = 99 trueRespGenPT = -1.0 if trueRespInd >= 0: for iG in xrange(len(genjets)): gjet = genjets[iG] if iG != trueRespInd: continue trueRespGenPT = gjet.pt trueRespFlv = gjet.partonFlavour break #if self.isQCDOrig: b = [] for iB in xrange(self.nBootstraps): b.append(1) self.out.fillBranch("nBootstrapWeight", self.nBootstraps) self.out.fillBranch("bootstrapWeight", b) ### Store output self.out.fillBranch("pseudoResp", MMPseudoResp) self.out.fillBranch("pseudoRespCSV", pJ.btagDeepB) self.out.fillBranch("pseudoRespPseudoGenPT", pseudoGenPT) self.out.fillBranch("pseudoRespPassFilter", passFilter) self.out.fillBranch("trueResp", trueResp if trueRespInd >= 0 else -1) self.out.fillBranch("trueRespFlv", trueRespFlv) self.out.fillBranch("trueRespGenPT", trueRespGenPT) return True
def prepareEvent(self, event): logging.debug('processing event %d' % event.event) ## select leading photon event._allPhotons = Collection(event, "Photon") event.photons = [] for pho in event._allPhotons: if not (pho.pt > 200 and abs(pho.eta) < 2.4 and (pho.cutBasedBitmap & 2) and pho.electronVeto): # medium ID continue event.photons.append(pho) if len(event.photons) < 1: return False ## selection on AK8 jets / drop if overlaps with a photon event.ak8jets = [] for fj in event._allAK8jets: if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)): continue # require jet and photon to be back-to-back if deltaPhi(event.photons[0], fj) < 2: continue # if deltaR(event.photons[0], fj) < self._jetConeSize: # continue event.ak8jets.append(fj) if len(event.ak8jets) < 1: return False ## ht event.ak4jets = [] for j in event._allJets: if not (j.pt > 25 and abs(j.eta) < 2.4 and (j.jetId & 2)): continue event.ak4jets.append(j) event.ht = sum([j.pt for j in event.ak4jets]) ## return True if passes selection return True
def transverseMass(obj, met): cos_dphi = np.cos(deltaPhi(obj, met)) return np.sqrt(2 * obj.pt * met.pt * (1 - cos_dphi))
def analyze(self, event): """ process event, return True (go to next module) or False (fail, go to next event) """ electrons = list(Collection(event, "Electron")) muons = list(Collection(event, "Muon")) jets = list(Collection(event, "Jet")) taus = list(Collection(event, "Tau")) flag = Object(event, "Flag") met = Object(event, "MET") # in case of systematic take the shifted values are default # For the central values, need to include jetMetTool all the time # Jet systematics if self.syst_var == "": syst_var = "nom" else: syst_var = self.syst_var ############################## ## corrections and MET ############################## try: var_jet_pts = getattr(event, "Jet_pt_{}".format(syst_var), None) if var_jet_pts: for i,jet in enumerate(jets): jet.pt = var_jet_pts[i] else: print 'WARNING: jet pts with variation {}' 'not available, using the nominal value'.format(syst_var) except: var_jet_pts = getattr(event, "Jet_pt_nom", None) for i,jet in enumerate(jets): jet.pt = var_jet_pts[i] try: var_met_pt = getattr(event, "MET_pt_{}".format(syst_var), None) var_met_phi = getattr(event, "MET_phi_{}".format(syst_var), None) if var_met_pt: met.pt = var_met_pt else: print 'WARNING: MET pt with variation ' '{} not available, using the nominal value'.format(syst_var) if var_met_phi: met.phi = var_met_phi else: print 'WARNING: MET phi with variation {}' 'not available, using the nominal value'.format(syst_var) except: var_met_pt = getattr(event, "MET_pt_nom", None) var_met_phi = getattr(event, "MET_phi_nom", None) if var_met_pt: met.pt = var_met_pt if var_met_phi: met.phi = var_met_phi met_p4 = ROOT.TLorentzVector() met_p4.SetPtEtaPhiM(met.pt,0.0,met.phi, 0.0) # Electrons Energy if "ElectronEn" in self.syst_var: (met_px, met_py) = ( met.pt*np.cos(met.phi), met.pt*np.sin(met.phi) ) if "Up" in self.syst_var: for i, elec in enumerate(electrons): met_px = met_px + (elec.energyErr)*np.cos(elec.phi)/math.cosh(elec.eta) met_py = met_py + (elec.energyErr)*np.sin(elec.phi)/math.cosh(elec.eta) elec.pt = elec.pt + elec.energyErr/math.cosh(elec.eta) else: for i, elec in enumerate(electrons): met_px = met_px - (elec.energyErr)*np.cos(elec.phi)/math.cosh(elec.eta) met_py = met_py - (elec.energyErr)*np.sin(elec.phi)/math.cosh(elec.eta) elec.pt = elec.pt - elec.energyErr/math.cosh(elec.eta) met.pt = math.sqrt(met_px**2 + met_py**2) met.phi = math.atan2(met_py, met_px) # Muons Energy if self.isMC: muons_pts = getattr(event, "Muon_corrected_pt") for i, muon in enumerate(muons): muon.pt = muons_pts[i] if "MuonEn" in self.syst_var: (met_px, met_py) = ( met.pt*np.cos(met.phi), met.pt*np.sin(met.phi) ) if "Up" in self.syst_var: muons_pts = getattr(event, "Muon_correctedUp_pt") for i, muon in enumerate(muons): met_px = met_px - (muons_pts[i] - muon.pt)*np.cos(muon.phi) met_py = met_py - (muons_pts[i] - muon.pt)*np.sin(muon.phi) muon.pt = muons_pts[i] else: muons_pts = getattr(event, "Muon_correctedDown_pt") for i, muon in enumerate(muons): met_px =met_px - (muons_pts[i] - muon.pt)*np.cos(muon.phi) met_py =met_py - (muons_pts[i] - muon.pt)*np.sin(muon.phi) muon.pt = muons_pts[i] met.pt = math.sqrt(met_px**2 + met_py**2) met.phi = math.atan2(met_py, met_px) pass_met_filter = self.met_filter(flag, True) # filling and contructing the event categorisation self.out.fillBranch("met_pt{}".format(self.syst_suffix), met.pt) self.out.fillBranch("met_phi{}".format(self.syst_suffix), met.phi) self.out.fillBranch("met_filter{}".format(self.syst_suffix), pass_met_filter) ############################## ## process leptons ############################## muons.sort(key=lambda muon: muon.pt, reverse=True) electrons.sort(key=lambda el: el.pt, reverse=True) # Choose tight-quality e/mu for event categorization good_muons = [] for idx,mu in enumerate(muons): isoLep = mu.pfRelIso04_all pass_ips = abs(mu.dxy) < 0.02 and abs(mu.dz) < 0.1 pass_fid = abs(mu.eta) < 2.4 and mu.pt >= (25 if idx==0 else 20) pass_ids = mu.tightId and isoLep <= 0.15 if pass_fid and pass_ids and pass_ips: good_muons.append(mu) good_electrons = [] for idy,el in enumerate(electrons): id_CB = el.cutBased # changing to MVA based ID : if el.pt >= (25 if idy==0 else 20) and abs(el.eta) <= 2.5 and self.electron_id(el, "90"): good_electrons.append(el) # let sort the muons in pt good_muons.sort(key=lambda x: x.pt, reverse=True) good_electrons.sort(key=lambda x: x.pt, reverse=True) # Find any remaining e/mu that pass looser selection extra_leptons = [] for mu in muons: isoLep = mu.pfRelIso04_all pass_ids = mu.softId and isoLep <= 0.25 pass_fid = abs(mu.eta) < 2.4 and mu.pt >= 7 if tk.closest(mu, good_muons)[1] < 0.01: continue if pass_fid and pass_ids: extra_leptons.append(mu) for el in electrons: pass_fid = abs(el.eta) < 2.5 and el.pt >= 7 if tk.closest(el, good_electrons)[1] < 0.01: continue if pass_fid and self.electron_id(el, "WPL"): extra_leptons.append(el) good_leptons = good_electrons + good_muons good_leptons.sort(key=lambda x: x.pt, reverse=True) extra_leptons.sort(key=lambda x: x.pt, reverse=True) ngood_leptons = len(good_leptons) nextra_leptons = len(extra_leptons) _leading_lep_flavor = 0 if len(good_muons) and len(good_electrons): if good_muons[0].pt > good_electrons[0].pt: _leading_lep_flavor = 1 _leading_lep_pt = good_leptons[0].pt if ngood_leptons else 0.0 _leading_lep_eta = good_leptons[0].eta if ngood_leptons else -99. _leading_lep_phi = good_leptons[0].phi if ngood_leptons else -99. _trailing_lep_pt = good_leptons[1].pt if ngood_leptons >= 2 else 0.0 _trailing_lep_eta = good_leptons[1].eta if ngood_leptons >= 2 else -99. _trailing_lep_phi = good_leptons[1].phi if ngood_leptons >= 2 else -99. self.out.fillBranch("ngood_leptons{}".format(self.syst_suffix), ngood_leptons) self.out.fillBranch("nextra_leptons{}".format(self.syst_suffix), nextra_leptons) self.out.fillBranch("leading_lep_flavor{}".format(self.syst_suffix), _leading_lep_flavor) self.out.fillBranch("leading_lep_pt{}".format(self.syst_suffix), _leading_lep_pt) self.out.fillBranch("leading_lep_eta{}".format(self.syst_suffix), _leading_lep_eta) self.out.fillBranch("leading_lep_phi{}".format(self.syst_suffix), _leading_lep_phi) self.out.fillBranch("trailing_lep_pt{}".format(self.syst_suffix), _trailing_lep_pt) self.out.fillBranch("trailing_lep_eta{}".format(self.syst_suffix), _trailing_lep_eta) self.out.fillBranch("trailing_lep_phi{}".format(self.syst_suffix), _trailing_lep_phi) if False: print "number of leptons [all, good, extra]: ", ngood_leptons, " : ", nextra_leptons print " CBId electrons : ", [e.cutBased for e in good_electrons] print " WP90 electrons : ", [e.mvaFall17Iso_WP90 for e in good_electrons] print " muons : ", [e.tightId for e in good_muons] print " lepton pts : ", [e.pt for e in good_leptons] # Leptons efficiency/Trigger/Isolation Scale factors # These are applied only of the first 2 leading leptons if self.isMC: w_muon_SF = w_electron_SF = 1.0 w_muon_SFUp = w_electron_SFUp = 1.0 w_muon_SFDown = w_electron_SFDown = 1.0 if ngood_leptons >= 2: if abs(good_leptons[0].pdgId) == 11: w_electron_SF *= good_leptons[0].SF w_electron_SFUp *= (good_leptons[0].SF + good_leptons[0].SFErr) w_electron_SFDown *= (good_leptons[0].SF - good_leptons[0].SFErr) if abs(good_leptons[0].pdgId) == 11: w_electron_SF *= good_leptons[1].SF w_electron_SFUp *= (good_leptons[1].SF + good_leptons[1].SFErr) w_electron_SFDown *= (good_leptons[1].SF - good_leptons[1].SFErr) if abs(good_leptons[0].pdgId) == 13: w_muon_SF *= good_leptons[0].SF w_muon_SFUp *= (good_leptons[0].SF + good_leptons[0].SFErr) w_muon_SFDown *= (good_leptons[0].SF - good_leptons[0].SFErr) if abs(good_leptons[1].pdgId) == 13: w_muon_SF *= good_leptons[1].SF w_muon_SFUp *= (good_leptons[1].SF + good_leptons[1].SFErr) w_muon_SFDown *= (good_leptons[1].SF - good_leptons[1].SFErr) self.out.fillBranch("w_muon_SF" , w_muon_SF ) self.out.fillBranch("w_muon_SFUp" , w_muon_SFUp ) self.out.fillBranch("w_muon_SFDown" , w_muon_SFDown ) self.out.fillBranch("w_electron_SF" , w_electron_SF ) self.out.fillBranch("w_electron_SFUp" , w_electron_SFUp ) self.out.fillBranch("w_electron_SFDown", w_electron_SFDown) # process taus had_taus = [] for tau in taus: if tk.closest(tau, good_leptons)[1] < 0.4: continue # only hadronic tau decay if tau.decayMode != 5: continue if tau.pt > 18 and abs(tau.eta) <= 2.3: had_taus.append(tau) _nhad_taus = len(had_taus) self.out.fillBranch("nhad_taus{}".format(self.syst_suffix), _nhad_taus) self.out.fillBranch("lead_tau_pt{}".format(self.syst_suffix), had_taus[0].pt if _nhad_taus else 0) ############################## ## process jet ############################## z_candidate = [] zcand_p4 = ROOT.TLorentzVector() emulated_met = ROOT.TLorentzVector() all_lepton_p4 = ROOT.TLorentzVector() rem_lepton_p4 = ROOT.TLorentzVector() good_jets = [] good_bjets = [] for jet in jets: if jet.pt < 30.0 or abs(jet.eta) > 4.7: continue if not jet.jetId: continue if tk.closest(jet, good_leptons)[1] < 0.4: continue good_jets.append(jet) # Count b-tag with medium WP DeepJet # ref : https://twiki.cern.ch/twiki/bin/view/CMS/BtagRecommendation if abs(jet.eta) <= 2.4 and jet.btagDeepFlavB > self.btag_id("loose"): good_bjets.append(jet) _ngood_jets = len(good_jets) _ngood_bjets = len(good_bjets) good_jets.sort(key=lambda jet: jet.pt, reverse=True) good_bjets.sort(key=lambda jet: jet.pt, reverse=True) _lead_jet_pt = good_jets[0].pt if _ngood_jets >= 1 else 0. _lead_jet_eta = good_jets[0].eta if _ngood_jets >= 1 else -99. _lead_jet_phi = good_jets[0].phi if _ngood_jets >= 1 else -99. _lead_jet_mass = good_jets[0].mass if _ngood_jets >= 1 else -99. _trail_jet_pt = good_jets[1].pt if _ngood_jets >= 2 else 0. _trail_jet_eta = good_jets[1].eta if _ngood_jets >= 2 else -99. _trail_jet_phi = good_jets[1].phi if _ngood_jets >= 2 else -99. _trail_jet_mass = good_jets[1].mass if _ngood_jets >= 2 else -99. _third_jet_pt = good_jets[2].pt if _ngood_jets >= 3 else 0. _third_jet_eta = good_jets[2].eta if _ngood_jets >= 3 else -99. _third_jet_phi = good_jets[2].phi if _ngood_jets >= 3 else -99. _third_jet_mass = good_jets[2].mass if _ngood_jets >= 3 else -99. _H_T = sum([jet.pt for jet in good_jets]) _dphi_j_met = tk.deltaPhi(good_jets[0], met.phi) if _ngood_jets >= 1 else -99. _lead_bjet_pt = good_bjets[0].pt if _ngood_bjets else 0. self.out.fillBranch("ngood_jets{}".format(self.syst_suffix), _ngood_jets) self.out.fillBranch("ngood_bjets{}".format(self.syst_suffix), _ngood_bjets) self.out.fillBranch("lead_jet_pt{}".format(self.syst_suffix), _lead_jet_pt) self.out.fillBranch("lead_jet_eta{}".format(self.syst_suffix), _lead_jet_eta) self.out.fillBranch("lead_jet_phi{}".format(self.syst_suffix), _lead_jet_phi) self.out.fillBranch("lead_jet_mass{}".format(self.syst_suffix), _lead_jet_mass) self.out.fillBranch("trail_jet_pt{}".format(self.syst_suffix), _trail_jet_pt) self.out.fillBranch("trail_jet_eta{}".format(self.syst_suffix), _trail_jet_eta) self.out.fillBranch("trail_jet_phi{}".format(self.syst_suffix), _trail_jet_phi) self.out.fillBranch("trail_jet_mass{}".format(self.syst_suffix), _trail_jet_mass) self.out.fillBranch("third_jet_pt{}".format(self.syst_suffix), _third_jet_pt) self.out.fillBranch("third_jet_eta{}".format(self.syst_suffix), _third_jet_eta) self.out.fillBranch("third_jet_phi{}".format(self.syst_suffix), _third_jet_phi) self.out.fillBranch("third_jet_mass{}".format(self.syst_suffix), _third_jet_mass) self.out.fillBranch("H_T{}".format(self.syst_suffix), _H_T) self.out.fillBranch("delta_phi_j_met{}".format(self.syst_suffix), _dphi_j_met) self.out.fillBranch("lead_bjet_pt{}".format(self.syst_suffix), _lead_bjet_pt) ############################## ## construct Z and category ############################## lep_category = 0 if ngood_leptons < 2: lep_category = -1 if ngood_leptons == 2 and nextra_leptons==0: # constructing the signal region if (good_leptons[0].pdgId * good_leptons[1].pdgId) == -11*11: lep_category = 1 # EE category if (good_leptons[0].pdgId * good_leptons[1].pdgId) == -11*13: lep_category = 2 # EM category if (good_leptons[0].pdgId * good_leptons[1].pdgId) == -13*13: lep_category = 3 # MM category z_candidate = [good_leptons[0], good_leptons[1]] zcand_p4 = good_leptons[0].p4() + good_leptons[1].p4() all_lepton_p4 = zcand_p4 elif ngood_leptons == 3 and nextra_leptons==0: # constructing the 3 leptons CR for pair in itertools.combinations(good_leptons, 2): if pair[0].pdgId == -pair[1].pdgId: zcand_ = pair[0].p4() + pair[1].p4() if abs(zcand_.M()-self.zmass) < abs(zcand_p4.M()-self.zmass): zcand_p4 = zcand_ z_candidate = list(pair) lep3_idx_ = 3 - good_leptons.index(pair[0]) - good_leptons.index(pair[1]) emulated_met = good_leptons[lep3_idx_].p4() + met_p4 all_lepton_p4 = zcand_ + good_leptons[lep3_idx_].p4() rem_lepton_p4 = good_leptons[lep3_idx_].p4() if abs(pair[0].pdgId) == 11: lep_category = 4 # EEL category if abs(pair[0].pdgId) == 13: lep_category = 5 # MML category elif ngood_leptons>=2 and (ngood_leptons + nextra_leptons) == 4: # constructing the 4 leptons CR for pair in itertools.combinations(good_leptons, 2): # checking if OSSF pair rem_pair = [x for x in good_leptons + extra_leptons if x not in pair] if (pair[0].pdgId == -pair[1].pdgId) and (rem_pair[0].pdgId == -rem_pair[1].pdgId): zcand_0 = pair[0].p4() + pair[1].p4() zcand_1 = rem_pair[0].p4() + rem_pair[1].p4() if abs(zcand_0.M()-self.zmass) < abs(zcand_p4.M()-self.zmass): zcand_p4 = zcand_0 z_candidate = pair emulated_met = zcand_1 + met_p4 all_lepton_p4 = zcand_p4 + zcand_1 rem_lepton_p4 = zcand_1 if abs(pair[0].pdgId) == 11: lep_category = 6 # EELL category if abs(pair[0].pdgId) == 13: lep_category = 7 # MMLL category else: # too many bad leptons, with no obvious meaning ? if ngood_leptons==1 and (ngood_leptons + nextra_leptons)>=1: lep_category = -2 elif ngood_leptons>=2 and (ngood_leptons + nextra_leptons)>=2: lep_category = -3 else: lep_category = -4 # filling MonoZ type of variables self.out.fillBranch("lep_category{}".format(self.syst_suffix), lep_category) self.out.fillBranch("Z_pt{}".format(self.syst_suffix), zcand_p4.Pt()) self.out.fillBranch("Z_eta{}".format(self.syst_suffix), zcand_p4.Eta()) self.out.fillBranch("Z_phi{}".format(self.syst_suffix), zcand_p4.Phi()) self.out.fillBranch("Z_mass{}".format(self.syst_suffix), zcand_p4.M()) self.out.fillBranch("Z_mt{}".format(self.syst_suffix), zcand_p4.Mt()) ############################## ## high level info ############################## _delta_zphi = tk.deltaPhi(z_candidate[0].phi, z_candidate[1].phi) if lep_category > 0 else -99 _delta_zdR = tk.deltaR(z_candidate[0].eta, z_candidate[0].phi, z_candidate[1].eta, z_candidate[1].phi,) if lep_category > 0 else -99 _delta_zeta = abs(z_candidate[0].eta - z_candidate[1].eta) if lep_category > 0 else -99 _delta_phi_zmet = tk.deltaPhi(zcand_p4.Phi(), met.phi) _vec_delta_balance = (met_p4 - zcand_p4).Pt()/zcand_p4.Pt() if zcand_p4.Pt() != 0 else -1 _sca_delta_balance = met.pt/zcand_p4.Pt() if zcand_p4.Pt() != 0 else -1 # hadronic recoil had_recoil_p4 = ROOT.TLorentzVector() had_recoil_p4 += met_p4 for lep in good_leptons + extra_leptons: had_recoil_p4 += lep.p4() had_recoil_p4 = -had_recoil_p4 _delta_met_rec = tk.deltaPhi(met.phi, had_recoil_p4.Phi()) if lep_category > 0 else -99 _MT = np.sqrt(2 * zcand_p4.Pt() * var_met_pt * (1 - np.cos(_delta_phi_zmet))) # defined as from https://arxiv.org/pdf/1808.09054.pdf _Ell = np.sqrt(zcand_p4.Mag2() + zcand_p4.M2()) _altMT = np.sqrt(np.power(_Ell + met_p4.Pt(),2) + (met_p4 + zcand_p4).Mag2()) # checking the transverse mass _rem_p4 = ROOT.TLorentzVector() _rem_p4.SetPtEtaPhiM(rem_lepton_p4.Pt(), 0, rem_lepton_p4.Phi(), 0) self.out.fillBranch("delta_phi_ll{}".format(self.syst_suffix), _delta_zphi) self.out.fillBranch("delta_eta_ll{}".format(self.syst_suffix), _delta_zeta) self.out.fillBranch("delta_R_ll{}".format(self.syst_suffix), _delta_zdR) self.out.fillBranch("delta_phi_ZMet{}".format(self.syst_suffix), _delta_phi_zmet) self.out.fillBranch("vec_balance{}".format(self.syst_suffix), _vec_delta_balance) self.out.fillBranch("sca_balance{}".format(self.syst_suffix), _sca_delta_balance) self.out.fillBranch("hadronic_recoil{}".format(self.syst_suffix), had_recoil_p4.Pt()) self.out.fillBranch("delta_met_rec{}".format(self.syst_suffix), _delta_met_rec) self.out.fillBranch("emulatedMET{}".format(self.syst_suffix), emulated_met.Pt()) self.out.fillBranch("emulatedMET_phi{}".format(self.syst_suffix), emulated_met.Phi()) self.out.fillBranch("mass_alllep{}".format(self.syst_suffix), all_lepton_p4.M()) self.out.fillBranch("pt_alllep{}".format(self.syst_suffix), all_lepton_p4.Pt()) self.out.fillBranch("remll_mass{}".format(self.syst_suffix), rem_lepton_p4.M()) self.out.fillBranch("MT{}".format(self.syst_suffix), _MT) self.out.fillBranch("altMT{}".format(self.syst_suffix), _altMT) self.out.fillBranch("trans_mass{}".format(self.syst_suffix), (_rem_p4 + met_p4).M()) # Let remove the negative categories with no obvious meaning meaning # This will reduce the size of most of the bacground and data if (lep_category > 0 and zcand_p4.Pt()>60 and zcand_p4.M() > 55 and zcand_p4.M() < 127): return True else: return False
def _prepareEvent(self, event): logging.debug('processing event %d' % event.event) ## met selection if event.MET_pt < 50.0: return False metLV = ROOT.TLorentzVector() metLV.SetPtEtaPhiM( event.MET_pt, 0.0, event.MET_phi, 0.0) ## muon selection event._allMuons = Collection(event, "Muon") event.muons = [] for muon in event._allMuons: if abs(muon.eta) < 2.4 and\ abs(muon.dxy) < 0.2 and\ abs(muon.dz) < 0.5:# and\ #muon.pfRelIso03_all < 0.15: drMuJet = deltaR(muon, event._allJets[muon.jetIdx]) if muon.jetIdx >= 0 else -999 ptRel = muon.pt if drMuJet > -999: jetforPtRel = event._allJets[muon.jetIdx] jetLV = ROOT.TLorentzVector() jetLV.SetPtEtaPhiM(jetforPtRel.pt, jetforPtRel.eta, jetforPtRel.phi, jetforPtRel.mass) thismuonLV = ROOT.TLorentzVector() thismuonLV.SetPtEtaPhiM(muon.pt, muon.eta, muon.phi, muon.mass) ptRel = muon.pt * math.cos(thismuonLV.Angle(jetLV.Vect())) if ptRel > 55.0 or drMuJet > 0.4: event.muons.append(muon) event.muonpTrel = ptRel event.drMuJet = drMuJet if (len(event.muons) != 1): return False muonLV = ROOT.TLorentzVector() muonLV.SetPtEtaPhiM( event.muons[0].pt, event.muons[0].eta, event.muons[0].phi, event.muons[0].mass ) ## b-tag AK4 jet selection event.ak4jets = [] for j in event._allJets: if not (j.pt > 25.0 and abs(j.eta) < 2.4 and (j.jetId & 2)): continue if j.btagCSVV2 > 0.8484 and\ abs(deltaPhi(j,event.muons[0])) < 2.0: event.ak4jets.append(j) if (len(event.ak4jets) < 1): return False ## selection on AK8 jets / drop if overlaps with a photon event.ak8jets = [] for fj in event._allAK8jets: if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)): continue if abs(deltaPhi(fj, event.muons[0])) > 2.0: event.ak8jets.append(fj) if (len(event.ak8jets)<1): return False ## selection on CA15 jets / drop if overlaps with a photon event.ca15jets = [] for fj in event._allCA15jets: if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)): continue if abs(deltaPhi(fj, event.muons[0])) > 2.0: event.ca15jets.append(fj) if (len(event.ca15jets)<1): return False ## require the leading ak8 & ca15 jets overlap if deltaR(event.ak8jets[0],event.ca15jets[0])>0.8: return False ##leptonic W pt cut WLV = ROOT.TLorentzVector() WLV = muonLV + metLV if WLV.Pt() < 250.0: return False ##Find gen top and compute top size (-999. if unmatched) if self.isMC: event.genTops = [] index = -1 matchIndex = [] for p in event.genParticles: index += 1 if not (abs(p.pdgId) == 6): continue pLV = ROOT.TLorentzVector() pLV.SetPtEtaPhiM(p.pt, p.eta, p.phi, p.mass) #if deltaR(event.ak8jets[0], p) < 1.0: event.genTops.append(p) matchIndex.append(index) #print "Found gen tops", len(event.genTops) event.topDecayParts = [] if matchIndex > -1: index = -1 event.genWs = [] genWindx = [] for p in event.genParticles: index += 1 #if not (p.genPartIdxMother in matchIndex): # continue pLV = ROOT.TLorentzVector() pLV.SetPtEtaPhiM(p.pt, p.eta, p.phi, p.mass) if abs(p.pdgId) == 5 and (p.genPartIdxMother in matchIndex): event.topDecayParts.append(p) if abs(p.pdgId) == 24 and (abs(event.genParticles[p.genPartIdxMother].pdgId) == 24): event.genWs.append(p) genWindx.append(index) #print "Found gen Ws", len(event.genWs) #print event.genWs for q in event.genParticles: if (q.genPartIdxMother in genWindx): qLV = ROOT.TLorentzVector() qLV.SetPtEtaPhiM(q.pt, q.eta, q.phi, q.mass) event.topDecayParts.append(q) #print "Top decay parts", len(event.topDecayParts) event.maxDR = -999. nMerged = 0 for d in event.topDecayParts: thisDR = deltaR(d,event.topDecayParts[-1]) if deltaR(d,event.ak8jets[0]) < 0.8: nMerged += 1 if thisDR > event.maxDR: event.maxDR = thisDR #print nMerged if nMerged >= 3: #print "full" event.isFullyMerged = 1 elif nMerged == 2: #print "semi" event.isSemiMerged = 1 elif nMerged <= 1: #print "un" event.isUnMerged = 1 ## return True if passes selection return True
def analyze(self, event): """ process event, return True (go to next module) or False (fail, go to next event) """ jets = list(Collection(event, "Jet")) fatjets = list(Collection(event, "FatJet")) taus = list(Collection(event, "Tau")) PFCands = list(Collection(event, "PFCands")) flag = Object(event, "Flag") met = Object(event, "MET") genpart = list(Collection(event, "GenPart")) met_p4 = ROOT.TLorentzVector() met_p4.SetPtEtaPhiM(met.pt, 0.0, met.phi, 0.0) # filling and contructing the event categorisation self.out.fillBranch("met_pt{}".format(self.syst_suffix), met.pt) self.out.fillBranch("met_phi{}".format(self.syst_suffix), met.phi) pass_met_filter = self.met_filter(flag, True) self.out.fillBranch("met_filter{}".format(self.syst_suffix), pass_met_filter) #look through all the PFCands. See here (https://github.com/SUEPPhysics/SUEPNano/blob/autumn18/python/addPFCands_cff.py) good_cands = [] fastjet_list = [] sum_cand_pt = 0.0 for cand in PFCands: if cand.trkPt < 1 or cand.fromPV < 2 or cand.trkEta > 2.5: continue good_cands.append(cand) sum_cand_pt += cand.trkPt fastjet_prep = (cand.trkPt, cand.trkEta, cand.trkPhi, cand.mass) fastjet_list.append(fastjet_prep) nCands = len(good_cands) ave_cand_pt = sum_cand_pt / nCands if nCands >= 1 else 0.0 #fill out the basics self.out.fillBranch("nCleaned_Cands{}".format(self.syst_suffix), nCands) self.out.fillBranch("HTTot{}".format(self.syst_suffix), sum_cand_pt) self.out.fillBranch("ave_cand_pt{}".format(self.syst_suffix), ave_cand_pt) #make new jet collection based on fastjet fastjet_in = np.array(fastjet_list[:], dtype=[('pT', 'f8'), ('eta', 'f8'), ('phi', 'f8'), ('mass', 'f8')]) sequence = pyjet.cluster( fastjet_in, R=1.5, p=-1) #p=-1,0,1 for anti-kt, aachen, and kt respectively fastjets = sequence.inclusive_jets(ptmin=3) self.out.fillBranch("ngood_fastjets".format(self.syst_suffix), len(fastjets)) #remove the 10 hardest tracks for SUEP_isr #fastjets.sort(key=lambda fastjet: len(fastjet), reverse=True) spher_tmp = ROOT.TLorentzVector() if len(fastjets) > 1: SUEP_cand = fastjets[0] ISR_cand = fastjets[1] if len(fastjets[1]) > len(fastjets[0]): SUEP_cand = fastjets[1] ISR_cand = fastjets[0] SUEP_pt = ROOT.TLorentzVector() SUEP_pt.SetPtEtaPhiM(SUEP_cand.pt, SUEP_cand.eta, SUEP_cand.phi, SUEP_cand.mass) boost_pt = SUEP_pt.BoostVector() boosted_cands = [] for cands in good_cands: spher_tmp.SetPtEtaPhiM(cands.trkPt, cands.trkEta, cands.trkPhi, cands.mass) spher_tmp.Boost(-boost_pt) if abs(tk.deltaPhi(spher_tmp.Phi(), ISR_cand.phi)) < 1.6: continue boosted_cands.append( [spher_tmp.Px(), spher_tmp.Py(), spher_tmp.Pz()]) try: sorted_evals = self.sphericity(boosted_cands, 2.0) except: sorted_evals = [0.0, 0.0, 0.0] SUEP_ch_spher = 1.5 * (sorted_evals[1] + sorted_evals[0]) SUEP_ch_aplan = 1.5 * sorted_evals[0] SUEP_ch_FW2M = 1.0 - 3.0 * (sorted_evals[2] * sorted_evals[1] + sorted_evals[2] * sorted_evals[0] + sorted_evals[1] * sorted_evals[0]) SUEP_ch_D = 27.0 * sorted_evals[2] * sorted_evals[ 1] * sorted_evals[0] self.out.fillBranch("SUEP_ch_nconst{}".format(self.syst_suffix), len(boosted_cands)) self.out.fillBranch("SUEP_ch_spher{}".format(self.syst_suffix), SUEP_ch_spher) self.out.fillBranch("SUEP_ch_aplan{}".format(self.syst_suffix), SUEP_ch_aplan) self.out.fillBranch("SUEP_ch_FW2M{}".format(self.syst_suffix), SUEP_ch_FW2M) self.out.fillBranch("SUEP_ch_D{}".format(self.syst_suffix), SUEP_ch_D) if len(fastjets) > 0: #looking at the highest pT fastjet for SUEP_pt self.out.fillBranch("SUEP_pt_pt{}".format(self.syst_suffix), fastjets[0].pt) self.out.fillBranch("SUEP_pt_m{}".format(self.syst_suffix), fastjets[0].mass) self.out.fillBranch("SUEP_pt_eta{}".format(self.syst_suffix), fastjets[0].eta) self.out.fillBranch("SUEP_pt_phi{}".format(self.syst_suffix), fastjets[0].phi) self.out.fillBranch("SUEP_pt_nconst{}".format(self.syst_suffix), len(fastjets[0])) sum_SUEP_pt = 0.0 girth_pt = 0.0 SUEP_pt = ROOT.TLorentzVector() SUEP_pt.SetPtEtaPhiM(fastjets[0].pt, fastjets[0].eta, fastjets[0].phi, fastjets[0].mass) boost_pt = SUEP_pt.BoostVector() spher_pt = [] for const in fastjets[0]: sum_SUEP_pt += const.pt dR = abs( tk.deltaR( const.eta, const.phi, fastjets[0].eta, fastjets[0].phi, )) girth_pt += dR * const.pt / fastjets[0].pt spher_tmp.SetPtEtaPhiM(const.pt, const.eta, const.phi, const.mass) spher_tmp.Boost(-boost_pt) spher_pt.append( [spher_tmp.Px(), spher_tmp.Py(), spher_tmp.Pz()]) try: sorted_evals = self.sphericity(spher_pt, 2.0) except: sorted_evals = [0.0, 0.0, 0.0] SUEP_pt_spher = 1.5 * (sorted_evals[1] + sorted_evals[0]) SUEP_pt_aplan = 1.5 * sorted_evals[0] SUEP_pt_FW2M = 1.0 - 3.0 * (sorted_evals[2] * sorted_evals[1] + sorted_evals[2] * sorted_evals[0] + sorted_evals[1] * sorted_evals[0]) SUEP_pt_D = 27.0 * sorted_evals[2] * sorted_evals[ 1] * sorted_evals[0] self.out.fillBranch("SUEP_pt_pt_ave{}".format(self.syst_suffix), sum_SUEP_pt / len(fastjets[0])) self.out.fillBranch("SUEP_pt_girth{}".format(self.syst_suffix), girth_pt) self.out.fillBranch("SUEP_pt_spher{}".format(self.syst_suffix), SUEP_pt_spher) self.out.fillBranch("SUEP_pt_aplan{}".format(self.syst_suffix), SUEP_pt_aplan) self.out.fillBranch("SUEP_pt_FW2M{}".format(self.syst_suffix), SUEP_pt_FW2M) self.out.fillBranch("SUEP_pt_D{}".format(self.syst_suffix), SUEP_pt_D) nconst_dphi1 = nconst_dphi3 = nconst_dphi5 = nconst_dphi7 = 0 if len(fastjets) > 1: if len(fastjets[0]) > len(fastjets[1]): SUEP_dphi_cand = fastjets[0] ISR_dphi_cand = fastjets[1] else: SUEP_dphi_cand = fastjets[1] ISR_dphi_cand = fastjets[0] SUEP_dphi_vector = ROOT.TLorentzVector() SUEP_dphi_vector.SetPtEtaPhiM(SUEP_dphi_cand.pt, SUEP_dphi_cand.eta, SUEP_dphi_cand.phi, SUEP_dphi_cand.mass) boost_dphi = SUEP_dphi_vector.BoostVector() spher_dphi1 = [] spher_dphi3 = [] spher_dphi5 = [] spher_dphi7 = [] for const in SUEP_dphi_cand: #dphi = abs(tk.deltaPhi(const.phi, ISR_dphi_cand.phi)) spher_tmp.SetPtEtaPhiM(const.pt, const.eta, const.phi, const.mass) spher_tmp.Boost(-boost_dphi) dphi = abs(tk.deltaPhi(spher_tmp.Phi(), ISR_dphi_cand.phi)) if dphi < 0.1: continue nconst_dphi1 += 1 spher_dphi1.append( [spher_tmp.Px(), spher_tmp.Py(), spher_tmp.Pz()]) if dphi < 0.3: continue nconst_dphi3 += 1 spher_dphi3.append( [spher_tmp.Px(), spher_tmp.Py(), spher_tmp.Pz()]) if dphi < 0.5: continue nconst_dphi5 += 1 spher_dphi5.append( [spher_tmp.Px(), spher_tmp.Py(), spher_tmp.Pz()]) if dphi < 0.7: continue nconst_dphi7 += 1 spher_dphi7.append( [spher_tmp.Px(), spher_tmp.Py(), spher_tmp.Pz()]) try: sorted_dphi1 = self.sphericity(spher_dphi1, 2.0) sorted_dphi3 = self.sphericity(spher_dphi3, 2.0) sorted_dphi5 = self.sphericity(spher_dphi5, 2.0) sorted_dphi7 = self.sphericity(spher_dphi7, 2.0) except: sorted_dphi1 = [0.0, 0.0, 0.0] sorted_dphi3 = [0.0, 0.0, 0.0] sorted_dphi5 = [0.0, 0.0, 0.0] sorted_dphi7 = [0.0, 0.0, 0.0] SUEP_dphi1_spher = 1.5 * (sorted_dphi1[1] + sorted_dphi1[0]) SUEP_dphi3_spher = 1.5 * (sorted_dphi3[1] + sorted_dphi3[0]) SUEP_dphi5_spher = 1.5 * (sorted_dphi5[1] + sorted_dphi5[0]) SUEP_dphi7_spher = 1.5 * (sorted_dphi7[1] + sorted_dphi7[0]) self.out.fillBranch("SUEP_dphi1_nconst{}".format(self.syst_suffix), nconst_dphi1) self.out.fillBranch("SUEP_dphi1_spher{}".format(self.syst_suffix), SUEP_dphi1_spher) self.out.fillBranch("SUEP_dphi3_nconst{}".format(self.syst_suffix), nconst_dphi3) self.out.fillBranch("SUEP_dphi3_spher{}".format(self.syst_suffix), SUEP_dphi3_spher) self.out.fillBranch("SUEP_dphi5_nconst{}".format(self.syst_suffix), nconst_dphi5) self.out.fillBranch("SUEP_dphi5_spher{}".format(self.syst_suffix), SUEP_dphi5_spher) self.out.fillBranch("SUEP_dphi7_nconst{}".format(self.syst_suffix), nconst_dphi7) self.out.fillBranch("SUEP_dphi7_spher{}".format(self.syst_suffix), SUEP_dphi7_spher) #look at the fastjet with the most constituents for SUEP_mult fastjets.sort(key=lambda fastjet: len(fastjet), reverse=True) self.out.fillBranch("SUEP_mult_pt{}".format(self.syst_suffix), fastjets[0].pt) self.out.fillBranch("SUEP_mult_m{}".format(self.syst_suffix), fastjets[0].mass) self.out.fillBranch("SUEP_mult_eta{}".format(self.syst_suffix), fastjets[0].eta) self.out.fillBranch("SUEP_mult_phi{}".format(self.syst_suffix), fastjets[0].phi) self.out.fillBranch("SUEP_mult_nconst{}".format(self.syst_suffix), len(fastjets[0])) sum_SUEP_mult = 0.0 girth_mult = 0.0 SUEP_mult = ROOT.TLorentzVector() SUEP_mult.SetPtEtaPhiM(fastjets[0].pt, fastjets[0].eta, fastjets[0].phi, fastjets[0].mass) boost_mult = SUEP_mult.BoostVector() spher_mult = [] unboost = [] #for const in fastjets[0]: # print(const.eta, const.phi, const.pt) #print("now for boosted") for const in fastjets[0]: sum_SUEP_mult += const.pt dR = abs( tk.deltaR( const.eta, const.phi, fastjets[0].eta, fastjets[0].phi, )) girth_mult += dR * const.pt / fastjets[0].pt spher_tmp.SetPtEtaPhiM(const.pt, const.eta, const.phi, const.mass) unboost.append( [spher_tmp.Px(), spher_tmp.Py(), spher_tmp.Pz()]) spher_tmp.Boost(-boost_mult) #print(spher_tmp.Eta(), spher_tmp.Phi(), spher_tmp.Pt()) spher_mult.append( [spher_tmp.Px(), spher_tmp.Py(), spher_tmp.Pz()]) try: sorted_evals = self.sphericity(unboost, 2.0) except: sorted_evals = [0.0, 0.0, 0.0] #print(sorted_evals) try: sorted_evals = self.sphericity(spher_mult, 2.0) except: sorted_evals = [0.0, 0.0, 0.0] #print(sorted_evals) SUEP_mult_spher = 1.5 * (sorted_evals[1] + sorted_evals[0]) SUEP_mult_aplan = 1.5 * sorted_evals[0] SUEP_mult_FW2M = 1.0 - 3.0 * (sorted_evals[2] * sorted_evals[1] + sorted_evals[2] * sorted_evals[0] + sorted_evals[1] * sorted_evals[0]) SUEP_mult_D = 27.0 * sorted_evals[2] * sorted_evals[ 1] * sorted_evals[0] self.out.fillBranch("SUEP_mult_pt_ave{}".format(self.syst_suffix), sum_SUEP_mult / len(fastjets[0])) self.out.fillBranch("SUEP_mult_girth{}".format(self.syst_suffix), girth_mult) self.out.fillBranch("SUEP_mult_spher{}".format(self.syst_suffix), SUEP_mult_spher) self.out.fillBranch("SUEP_mult_aplan{}".format(self.syst_suffix), SUEP_mult_aplan) self.out.fillBranch("SUEP_mult_FW2M{}".format(self.syst_suffix), SUEP_mult_FW2M) self.out.fillBranch("SUEP_mult_D{}".format(self.syst_suffix), SUEP_mult_D) good_jets = [] good_bjets = [] HT = 0.0 for jet in jets: if jet.pt < 30.0 or abs(jet.eta) > 4.7: continue if not jet.jetId: continue #if tk.closest(jet, good_leptons)[1] < 0.4: # continue good_jets.append(jet) HT += jet.pt # Count b-tag with medium WP DeepCSV # ref : https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X if abs(jet.eta) <= 2.4 and jet.btagDeepB > self.btag_id("medium"): good_bjets.append(jet) good_jets.sort(key=lambda jet: jet.pt, reverse=True) good_bjets.sort(key=lambda jet: jet.pt, reverse=True) _dphi_j_met = tk.deltaPhi(good_jets[0], met.phi) if len(good_jets) else -99.0 _lead_jet_pt = good_jets[0].pt if len(good_jets) else 0.0 _lead_bjet_pt = good_bjets[0].pt if len(good_bjets) else 0.0 self.out.fillBranch("HT{}".format(self.syst_suffix), HT) self.out.fillBranch("ngood_jets{}".format(self.syst_suffix), len(good_jets)) self.out.fillBranch("ngood_bjets{}".format(self.syst_suffix), len(good_bjets)) self.out.fillBranch("lead_jet_pt{}".format(self.syst_suffix), _lead_jet_pt) self.out.fillBranch("lead_bjet_pt{}".format(self.syst_suffix), _lead_bjet_pt) self.out.fillBranch("delta_phi_j_met{}".format(self.syst_suffix), _dphi_j_met) # process taus had_taus = [] for tau in taus: #if tk.closest(tau, good_leptons)[1] < 0.4: # continue # only hadronic tau decay if tau.decayMode != 5: continue if tau.pt > 18 and abs(tau.eta) <= 2.3: had_taus.append(tau) self.out.fillBranch("nhad_taus{}".format(self.syst_suffix), len(had_taus)) self.out.fillBranch("lead_tau_pt{}".format(self.syst_suffix), had_taus[0].pt if len(had_taus) else 0) # This will reduce the size of most of the background and data if (len(fastjets) > 0): return True else: return False
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" self.correctJetsAndMET(event) self.selectLeptons(event) if self.prepareEvent(event) is False: return False self.loadGenHistory(event) ## event variables htfwd_ = 0. htveryfwd_ = 0. for j in event._allJets: #if not (j.pt > 20 and abs(j.eta) < 2.4 and (j.jetId & 2)): if not (j.pt > 25 and (j.jetId & 2)): continue if (abs(j.eta) > 2.4): htfwd_ += j.pt if (abs(j.eta) > 3.5): htveryfwd_ += j.pt self.out.fillBranch("ht", event.ht) self.out.fillBranch("htfwd", htfwd_) self.out.fillBranch("htveryfwd", htveryfwd_) self.out.fillBranch("nlep", len(event.looseLeptons)) self.out.fillBranch("met", event.met.pt) ## count bjets away from fatjet nlb_fj_pihalf_ = 0 nmb_fj_pihalf_ = 0 ntb_fj_pihalf_ = 0 nb_fj_pi_ = 0 for j in event.bljets: if abs(deltaPhi(j, event.fatjets[0])) > 3.14: nb_fj_pi_ += 1 if abs(deltaPhi(j, event.fatjets[0])) > 3.14 / 2.: nlb_fj_pihalf_ += 1 for j in event.bmjets: if abs(deltaPhi(j, event.fatjets[0])) > 3.14 / 2.: nmb_fj_pihalf_ += 1 for j in event.btjets: if abs(deltaPhi(j, event.fatjets[0])) > 3.14 / 2.: ntb_fj_pihalf_ += 1 nb_away_fj_ = 0 for j in event.bljets: if deltaR(j, event.fatjets[0]) > 1.: nb_away_fj_ += 1 self.out.fillBranch("nlb_fj_pihalf", nlb_fj_pihalf_) self.out.fillBranch("nmb_fj_pihalf", nmb_fj_pihalf_) self.out.fillBranch("ntb_fj_pihalf", ntb_fj_pihalf_) self.out.fillBranch("nb_fj_pi", nb_fj_pi_) self.out.fillBranch("nb_away_fj", nb_away_fj_) self.fillBaseEventInfo(event) self.fillFatJetInfo(event) return True
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") photons = Collection(event, "Photon") try: genparts = Collection(event, "GenPart") except: pass tight_muons = [] loose_but_not_tight_muons = [] tight_electrons = [] loose_but_not_tight_electrons = [] tight_photons = [] tight_jets = [] for i in range(0, len(muons)): if muons[i].pt < 20: continue if abs(muons[i].eta) > 2.4: continue if muons[i].tightId and muons[i].pfRelIso04_all < 0.15: tight_muons.append(i) elif muons[i].pfRelIso04_all < 0.4: loose_but_not_tight_muons.append(i) for i in range(0, len(electrons)): if electrons[i].pt / electrons[i].eCorr < 20: continue if abs(electrons[i].eta + electrons[i].deltaEtaSC) > 2.5: continue if (abs(electrons[i].eta + electrons[i].deltaEtaSC) < 1.479 and abs(electrons[i].dz) < 0.1 and abs(electrons[i].dxy) < 0.05) or ( abs(electrons[i].eta + electrons[i].deltaEtaSC) > 1.479 and abs(electrons[i].dz) < 0.2 and abs(electrons[i].dxy) < 0.1): if electrons[i].cutBased >= 3: tight_electrons.append(i) elif electrons[i].cutBased >= 1: loose_but_not_tight_electrons.append(i) for i in range(0, len(photons)): if photons[i].pt / photons[i].eCorr < 20: continue #if not ((abs(photons[i].eta) < 1.4442) or (1.566 < abs(photons[i].eta) and abs(photons[i].eta) < 2.5) ): if not ( (abs(photons[i].eta) < 1.4442) or (1.566 < abs(photons[i].eta) and abs(photons[i].eta) < 2.5)): continue mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) | (1 << 13) mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 13) mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | ( 1 << 13) mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | ( 1 << 13 ) #invert the medium photon ID with the sigma_ietaieta cut removed bitmap = photons[i].vidNestedWPBitmap & mask1 #first add the photons that pass the full ID if not (bitmap == mask1): continue if not ((bitmap == mask1) or (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4) or (bitmap == mask5)): continue #if photons[i].cutBased == 0 or photons[i].cutBased == 1: # continue # if not photons[i].electronVeto: # continue if photons[i].pixelSeed: continue pass_lepton_dr_cut = True for j in range(0, len(tight_muons)): if deltaR(muons[tight_muons[j]].eta, muons[tight_muons[j]].phi, photons[i].eta, photons[i].phi) < 0.5: pass_lepton_dr_cut = False for j in range(0, len(tight_electrons)): if deltaR(electrons[tight_electrons[j]].eta, electrons[tight_electrons[j]].phi, photons[i].eta, photons[i].phi) < 0.5: pass_lepton_dr_cut = False if not pass_lepton_dr_cut: continue tight_photons.append(i) for i in range(0, len(photons)): if photons[i].pt / photons[i].eCorr < 20: continue #if not ((abs(photons[i].eta) < 1.4442) or (1.566 < abs(photons[i].eta) and abs(photons[i].eta) < 2.5) ): if not ( (abs(photons[i].eta) < 1.4442) or (1.566 < abs(photons[i].eta) and abs(photons[i].eta) < 2.5)): continue mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) | (1 << 13) mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 13) mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | ( 1 << 13) mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | ( 1 << 13 ) #invert the medium photon ID with the sigma_ietaieta cut removed bitmap = photons[i].vidNestedWPBitmap & mask1 #after adding the photons that pass the full ID, add the photons that pass the inverted ID if (bitmap == mask1): continue if not ((bitmap == mask1) or (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4) or (bitmap == mask5)): continue #if photons[i].cutBased == 0 or photons[i].cutBased == 1: # continue # if not photons[i].electronVeto: # continue if photons[i].pixelSeed: continue pass_lepton_dr_cut = True for j in range(0, len(tight_muons)): if deltaR(muons[tight_muons[j]].eta, muons[tight_muons[j]].phi, photons[i].eta, photons[i].phi) < 0.5: pass_lepton_dr_cut = False for j in range(0, len(tight_electrons)): if deltaR(electrons[tight_electrons[j]].eta, electrons[tight_electrons[j]].phi, photons[i].eta, photons[i].phi) < 0.5: pass_lepton_dr_cut = False if not pass_lepton_dr_cut: continue tight_photons.append(i) if len(tight_photons) == 0: return False njets = 0 for i in range(0, len(jets)): if jets[i].pt < 30: continue if abs(jets[i].eta) > 4.7: continue if not jets[i].jetId & (1 << 0): continue njets += 1 for i in range(0, len(jets)): if jets[i].pt < 30: continue if abs(jets[i].eta) > 4.7: continue if not jets[i].jetId & (1 << 0): continue #pass_photon_dr_cut = True #for j in range(0,len(tight_photons)): # print "deltaR(photons[tight_photons[j]].eta,photons[tight_photons[j]].phi,jets[i].eta,jets[i].phi) = " + str(deltaR(photons[tight_photons[j]].eta,photons[tight_photons[j]].phi,jets[i].eta,jets[i].phi)) # if deltaR(photons[tight_photons[j]].eta,photons[tight_photons[j]].phi,jets[i].eta,jets[i].phi) < 0.5: # pass_photon_dr_cut = False #if not pass_photon_dr_cut: # continue if deltaR(photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, jets[i].eta, jets[i].phi) < 0.5: continue pass_lepton_dr_cut = True for j in range(0, len(tight_muons)): if deltaR(muons[tight_muons[j]].eta, muons[tight_muons[j]].phi, jets[i].eta, jets[i].phi) < 0.5: pass_lepton_dr_cut = False for j in range(0, len(tight_electrons)): if deltaR(electrons[tight_electrons[j]].eta, electrons[tight_electrons[j]].phi, jets[i].eta, jets[i].phi) < 0.5: pass_lepton_dr_cut = False for j in range(0, len(loose_but_not_tight_muons)): if deltaR(muons[loose_but_not_tight_muons[j]].eta, muons[loose_but_not_tight_muons[j]].phi, jets[i].eta, jets[i].phi) < 0.5: pass_lepton_dr_cut = False for j in range(0, len(loose_but_not_tight_electrons)): if deltaR(electrons[loose_but_not_tight_electrons[j]].eta, electrons[loose_but_not_tight_electrons[j]].phi, jets[i].eta, jets[i].phi) < 0.5: pass_lepton_dr_cut = False if not pass_lepton_dr_cut: continue tight_jets.append(i) if len(tight_jets) < 2: return False if jets[tight_jets[0]].btagCSVV2 < 0.8484 and jets[ tight_jets[1]].btagCSVV2 < 0.8484: self.out.fillBranch("btagging_selection", 1) else: self.out.fillBranch("btagging_selection", 0) if jets[tight_jets[0]].pt < 40: return False if jets[tight_jets[1]].pt < 30: return False if abs(jets[tight_jets[0]].eta) > 4.7: return False if abs(jets[tight_jets[1]].eta) > 4.7: return False if (jets[tight_jets[0]].p4() + jets[tight_jets[1]].p4()).M() < 200: return False #if abs(jets[0].p4().Eta() - jets[1].p4().Eta()) < 2.5: # return False if photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr < 20: return False #if not (abs(photons[tight_photons[0]].eta) < 1.4442): #if not (abs(photons[tight_photons[0]].eta) < 1.4442): # return False if not ((abs(photons[tight_photons[0]].eta) < 1.4442) or (1.566 < abs(photons[tight_photons[0]].eta) and abs(photons[tight_photons[0]].eta) < 2.5)): return False if deltaR(photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, jets[tight_jets[0]].eta, jets[tight_jets[0]].phi) < 0.5: return False if deltaR(photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, jets[tight_jets[1]].eta, jets[tight_jets[1]].phi) < 0.5: return False if deltaR(jets[tight_jets[0]].eta, jets[tight_jets[0]].phi, jets[tight_jets[1]].eta, jets[tight_jets[1]].phi) < 0.5: return False #if photons[tight_photons[0]].cutBased == 0 or photons[tight_photons[0]].cutBased == 1: # return False # if not photons[tight_photons[0]].electronVeto: # return False if photons[tight_photons[0]].pixelSeed: return False #if event.MET_pt < 35: # return False if abs(deltaPhi(event.MET_phi, jets[tight_jets[0]].phi)) < 0.4: return False if abs(deltaPhi(event.MET_phi, jets[tight_jets[1]].phi)) < 0.4: return False if len(tight_muons) + len(loose_but_not_tight_muons) + len( tight_electrons) + len(loose_but_not_tight_electrons) > 1: return False isprompt_mask = (1 << 0) #isPrompt isprompttaudecayproduct_mask = (1 << 4) #isPromptTauDecayProduct is_lepton_real = 0 if len(tight_muons) == 1: try: for i in range(0, len(genparts)): if genparts[i].pt > 5 and abs( genparts[i].pdgId) == 13 and ( (genparts[i].statusFlags & isprompt_mask == isprompt_mask) or (genparts[i].statusFlags & isprompttaudecayproduct_mask == isprompttaudecayproduct_mask)) and deltaR( muons[tight_muons[0]].eta, muons[tight_muons[0]].phi, genparts[i].eta, genparts[i].phi) < 0.3: is_lepton_real = 1 except: pass if not (event.HLT_IsoMu24 or event.HLT_IsoTkMu24): return False if deltaR(photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, muons[tight_muons[0]].eta, muons[tight_muons[0]].phi) < 0.5: return False if muons[tight_muons[0]].pt < 25: return False if abs(muons[tight_muons[0]].eta) > 2.4: return False if muons[tight_muons[0]].pfRelIso04_all > 0.15: return False if not muons[tight_muons[0]].tightId: return False #if sqrt(2*muons[tight_muons[0]].pt*event.MET_pt*(1 - cos(event.MET_phi - muons[tight_muons[0]].phi))) < 30: # return False self.out.fillBranch( "mt", sqrt(2 * muons[tight_muons[0]].pt * event.MET_pt * (1 - cos(event.MET_phi - muons[tight_muons[0]].phi)))) print "selected muon event: " + str(event.event) + " " + str( event.luminosityBlock) + " " + str(event.run) mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) | (1 << 13) mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 13) mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | ( 1 << 13) mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | ( 1 << 13 ) #invert the medium photon ID with the sigma_ietaieta cut removed bitmap = photons[tight_photons[0]].vidNestedWPBitmap & mask1 if (bitmap == mask1): self.out.fillBranch("photon_selection", 2) elif (bitmap == mask5): self.out.fillBranch("photon_selection", 1) elif (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4): self.out.fillBranch("photon_selection", 0) else: assert (0) self.out.fillBranch("is_lepton_real", is_lepton_real) self.out.fillBranch("lepton_pdg_id", 13) self.out.fillBranch("lepton_pt", muons[tight_muons[0]].pt) self.out.fillBranch("lepton_eta", muons[tight_muons[0]].eta) self.out.fillBranch("lepton_phi", muons[tight_muons[0]].phi) self.out.fillBranch("met", event.MET_pt) self.out.fillBranch( "photon_pt", photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr) self.out.fillBranch("photon_eta", photons[tight_photons[0]].eta) self.out.fillBranch("photon_phi", photons[tight_photons[0]].phi) self.out.fillBranch("mjj", (jets[tight_jets[0]].p4() + jets[tight_jets[1]].p4()).M()) self.out.fillBranch("mlg", (muons[tight_muons[0]].p4() + photons[tight_photons[0]].p4()).M()) self.out.fillBranch("is_lepton_tight", 1) elif len(loose_but_not_tight_muons) == 1: try: for i in range(0, len(genparts)): if genparts[i].pt > 5 and abs( genparts[i].pdgId) == 13 and ( (genparts[i].statusFlags & isprompt_mask == isprompt_mask) or (genparts[i].statusFlags & isprompttaudecayproduct_mask == isprompttaudecayproduct_mask)) and deltaR( muons[loose_but_not_tight_muons[0]].eta, muons[loose_but_not_tight_muons[0]].phi, genparts[i].eta, genparts[i].phi) < 0.3: is_lepton_real = 1 except: pass if not (event.HLT_IsoMu24 or event.HLT_IsoTkMu24): return False if deltaR(photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, muons[loose_but_not_tight_muons[0]].eta, muons[loose_but_not_tight_muons[0]].phi) < 0.5: return False if muons[loose_but_not_tight_muons[0]].pt < 25: return False if abs(muons[loose_but_not_tight_muons[0]].eta) > 2.4: return False #if sqrt(2*muons[loose_but_not_tight_muons[0]].pt*event.MET_pt*(1 - cos(event.MET_phi - muons[loose_but_not_tight_muons[0]].phi))) < 30: # return False self.out.fillBranch( "mt", sqrt(2 * muons[loose_but_not_tight_muons[0]].pt * event.MET_pt * (1 - cos(event.MET_phi - muons[loose_but_not_tight_muons[0]].phi)))) mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) | (1 << 13) mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 13) mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | ( 1 << 13) mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | ( 1 << 13 ) #invert the medium photon ID with the sigma_ietaieta cut removed bitmap = photons[tight_photons[0]].vidNestedWPBitmap & mask1 if (bitmap == mask1): self.out.fillBranch("photon_selection", 2) elif (bitmap == mask5): self.out.fillBranch("photon_selection", 1) elif (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4): self.out.fillBranch("photon_selection", 0) else: assert (0) self.out.fillBranch("is_lepton_real", is_lepton_real) self.out.fillBranch("lepton_pdg_id", 13) self.out.fillBranch("lepton_pt", muons[loose_but_not_tight_muons[0]].pt) self.out.fillBranch("lepton_eta", muons[loose_but_not_tight_muons[0]].eta) self.out.fillBranch("lepton_phi", muons[loose_but_not_tight_muons[0]].phi) self.out.fillBranch("met", event.MET_pt) self.out.fillBranch( "photon_pt", photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr) self.out.fillBranch("photon_eta", photons[tight_photons[0]].eta) self.out.fillBranch("photon_phi", photons[tight_photons[0]].phi) self.out.fillBranch("mjj", (jets[tight_jets[0]].p4() + jets[tight_jets[1]].p4()).M()) self.out.fillBranch("mlg", (muons[loose_but_not_tight_muons[0]].p4() + photons[tight_photons[0]].p4()).M()) self.out.fillBranch("is_lepton_tight", 0) elif len(tight_electrons) == 1: try: for i in range(0, len(genparts)): if genparts[i].pt > 5 and abs( genparts[i].pdgId) == 11 and ( (genparts[i].statusFlags & isprompt_mask == isprompt_mask) or (genparts[i].statusFlags & isprompttaudecayproduct_mask == isprompttaudecayproduct_mask)) and deltaR( electrons[tight_electrons[0]].eta, electrons[tight_electrons[0]].phi, genparts[i].eta, genparts[i].phi) < 0.3: is_lepton_real = 1 except: pass if not event.HLT_Ele27_WPTight_Gsf: return False if electrons[tight_electrons[0]].cutBased == 0 or electrons[ tight_electrons[0]].cutBased == 1: return False if deltaR(photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, electrons[tight_electrons[0]].eta, electrons[tight_electrons[0]].phi) < 0.5: return False if electrons[tight_electrons[0]].pt / electrons[ tight_electrons[0]].eCorr < 30: return False if abs(electrons[tight_electrons[0]].eta) > 2.5: return False ele_p4 = electrons[tight_electrons[0]].p4() pho_p4 = photons[tight_photons[0]].p4() ele_p4.SetPtEtaPhiM( ele_p4.Pt() / electrons[tight_electrons[0]].eCorr, ele_p4.Eta(), ele_p4.Phi(), ele_p4.M()) pho_p4.SetPtEtaPhiM(pho_p4.Pt() / photons[tight_photons[0]].eCorr, pho_p4.Eta(), pho_p4.Phi(), pho_p4.M()) # if (ele_p4 + pho_p4).M() > 81.2 and (ele_p4 + pho_p4).M() < 101.2: # if (ele_p4 + pho_p4).M() > 76.2 and (ele_p4 + pho_p4).M() < 106.2: # return False #if sqrt(2*electrons[tight_electrons[0]].pt/electrons[tight_electrons[0]].eCorr*event.MET_pt*(1 - cos(event.MET_phi - electrons[tight_electrons[0]].phi))) < 30: # return False self.out.fillBranch( "mt", sqrt(2 * electrons[tight_electrons[0]].pt / electrons[tight_electrons[0]].eCorr * event.MET_pt * (1 - cos(event.MET_phi - electrons[tight_electrons[0]].phi)))) mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) | (1 << 13) mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 13) mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | ( 1 << 13) mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | ( 1 << 13 ) #invert the medium photon ID with the sigma_ietaieta cut removed bitmap = photons[tight_photons[0]].vidNestedWPBitmap & mask1 if (bitmap == mask1): self.out.fillBranch("photon_selection", 2) elif (bitmap == mask5): self.out.fillBranch("photon_selection", 1) elif (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4): self.out.fillBranch("photon_selection", 0) else: assert (0) self.out.fillBranch("is_lepton_real", is_lepton_real) self.out.fillBranch("lepton_pdg_id", 11) self.out.fillBranch("lepton_pt", electrons[tight_electrons[0]].pt) self.out.fillBranch("lepton_eta", electrons[tight_electrons[0]].eta) self.out.fillBranch("lepton_phi", electrons[tight_electrons[0]].phi) self.out.fillBranch("met", event.MET_pt) self.out.fillBranch( "photon_pt", photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr) self.out.fillBranch("photon_eta", photons[tight_photons[0]].eta) self.out.fillBranch("photon_phi", photons[tight_photons[0]].phi) self.out.fillBranch("mjj", (jets[tight_jets[0]].p4() + jets[tight_jets[1]].p4()).M()) self.out.fillBranch("mlg", (ele_p4 + pho_p4).M()) self.out.fillBranch("is_lepton_tight", 1) print "selected electron event: " + str(event.event) + " " + str( event.luminosityBlock) + " " + str(event.run) elif len(loose_but_not_tight_electrons) == 1: try: for i in range(0, len(genparts)): if genparts[i].pt > 5 and abs( genparts[i].pdgId ) == 11 and ( (genparts[i].statusFlags & isprompt_mask == isprompt_mask) or (genparts[i].statusFlags & isprompttaudecayproduct_mask == isprompttaudecayproduct_mask)) and deltaR( electrons[loose_but_not_tight_electrons[0]].eta, electrons[loose_but_not_tight_electrons[0]].phi, genparts[i].eta, genparts[i].phi) < 0.3: is_lepton_real = 1 except: pass if not event.HLT_Ele27_WPTight_Gsf: return False if deltaR(photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, electrons[loose_but_not_tight_electrons[0]].eta, electrons[loose_but_not_tight_electrons[0]].phi) < 0.5: return False if electrons[loose_but_not_tight_electrons[0]].pt / electrons[ loose_but_not_tight_electrons[0]].eCorr < 30: return False if abs(electrons[loose_but_not_tight_electrons[0]].eta) > 2.5: return False ele_p4 = electrons[loose_but_not_tight_electrons[0]].p4() pho_p4 = photons[tight_photons[0]].p4() ele_p4.SetPtEtaPhiM( ele_p4.Pt() / electrons[loose_but_not_tight_electrons[0]].eCorr, ele_p4.Eta(), ele_p4.Phi(), ele_p4.M()) pho_p4.SetPtEtaPhiM(pho_p4.Pt() / photons[tight_photons[0]].eCorr, pho_p4.Eta(), pho_p4.Phi(), pho_p4.M()) # if (ele_p4 + pho_p4).M() > 81.2 and (ele_p4 + pho_p4).M() < 101.2: # if (ele_p4 + pho_p4).M() > 76.2 and (ele_p4 + pho_p4).M() < 106.2: # return False #if sqrt(2*electrons[loose_but_not_tight_electrons[0]].pt/electrons[loose_but_not_tight_electrons[0]].eCorr*event.MET_pt*(1 - cos(event.MET_phi - electrons[loose_but_not_tight_electrons[0]].phi))) < 30: # return False self.out.fillBranch( "mt", sqrt(2 * electrons[loose_but_not_tight_electrons[0]].pt / electrons[loose_but_not_tight_electrons[0]].eCorr * event.MET_pt * (1 - cos(event.MET_phi - electrons[loose_but_not_tight_electrons[0]].phi)))) mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) | (1 << 13) mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 11) mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | ( 1 << 13) mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | ( 1 << 13) mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | ( 1 << 13 ) #invert the medium photon ID with the sigma_ietaieta cut removed bitmap = photons[tight_photons[0]].vidNestedWPBitmap & mask1 if (bitmap == mask1): self.out.fillBranch("photon_selection", 2) elif (bitmap == mask5): self.out.fillBranch("photon_selection", 1) elif (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4): self.out.fillBranch("photon_selection", 0) else: assert (0) self.out.fillBranch("is_lepton_real", is_lepton_real) self.out.fillBranch("lepton_pdg_id", 11) self.out.fillBranch("lepton_pt", electrons[loose_but_not_tight_electrons[0]].pt) self.out.fillBranch( "lepton_eta", electrons[loose_but_not_tight_electrons[0]].eta) self.out.fillBranch( "lepton_phi", electrons[loose_but_not_tight_electrons[0]].phi) self.out.fillBranch("met", event.MET_pt) self.out.fillBranch( "photon_pt", photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr) self.out.fillBranch("photon_eta", photons[tight_photons[0]].eta) self.out.fillBranch("photon_phi", photons[tight_photons[0]].phi) self.out.fillBranch("mjj", (jets[tight_jets[0]].p4() + jets[tight_jets[1]].p4()).M()) self.out.fillBranch("mlg", (ele_p4 + pho_p4).M()) self.out.fillBranch("is_lepton_tight", 0) else: return False #print event.event #self.out.fillBranch("EventMass",eventSum.M()) #if eventSum.M() < 2000: # return False #else: # return True photon_gen_matching = 0 try: for i in range(0, len(genparts)): if genparts[i].pt > 5 and abs( genparts[i].pdgId ) == 13 and genparts[i].status == 1 and ( (genparts[i].statusFlags & isprompt_mask == isprompt_mask) or (genparts[i].statusFlags & isprompttaudecayproduct_mask == isprompttaudecayproduct_mask)) and deltaR( photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, genparts[i].eta, genparts[i].phi) < 0.3: photon_gen_matching += 1 break for i in range(0, len(genparts)): if genparts[i].pt > 5 and abs( genparts[i].pdgId ) == 11 and genparts[i].status == 1 and ( (genparts[i].statusFlags & isprompt_mask == isprompt_mask) or (genparts[i].statusFlags & isprompttaudecayproduct_mask == isprompttaudecayproduct_mask)) and deltaR( photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, genparts[i].eta, genparts[i].phi) < 0.3: photon_gen_matching += 2 break for i in range(0, len(genparts)): if genparts[i].pt > 5 and genparts[i].pdgId == 22 and genparts[ i].status == 1 and ( (genparts[i].statusFlags & isprompt_mask == isprompt_mask) or (genparts[i].statusFlags & isprompttaudecayproduct_mask == isprompttaudecayproduct_mask)) and deltaR( photons[tight_photons[0]].eta, photons[tight_photons[0]].phi, genparts[i].eta, genparts[i].phi) < 0.3: if genparts[i].genPartIdxMother >= 0 and ( abs(genparts[genparts[i].genPartIdxMother].pdgId) == 11 or abs( genparts[genparts[i].genPartIdxMother].pdgId) == 13 or abs( genparts[genparts[i].genPartIdxMother].pdgId) == 15): photon_gen_matching += 8 else: photon_gen_matching += 4 break except: pass self.out.fillBranch("photon_gen_matching", photon_gen_matching) try: self.out.fillBranch("gen_weight", event.Generator_weight) except: pass try: self.out.fillBranch("npu", event.Pileup_nPU) self.out.fillBranch("ntruepu", event.Pileup_nTrueInt) except: pass self.out.fillBranch("njets", njets) self.out.fillBranch("npvs", event.PV_npvs) self.out.fillBranch("event", event.event) self.out.fillBranch("lumi", event.luminosityBlock) self.out.fillBranch("run", event.run) return True
def prepareEvent(self, event): logging.debug('processing event %d' % event.event) ## met selection if event.met.pt < 50.0: return False ## muon selection muSubJets = [] for j in Collection(event, "CustomAK4CHS"): if j.pt > 30 and abs(j.eta) < 2.4: muSubJets.append(j) event._allMuons = Collection(event, "Muon") event.muons = [] for muon in event._allMuons: if muon.pt > 55 and abs(muon.eta) < 2.4 and muon.tightId and abs( muon.dxy) < 0.2 and abs(muon.dz) < 0.5: j, muon.drjet = closest(muon, muSubJets) muon.ptrel = muon.p4().Perp(j.p4().Vect()) if j else 0 # if muon.pfRelIso04_all < 0.15: if muon.drjet > 0.4 or muon.ptrel > 25: event.muons.append(muon) if len(event.muons) != 1: return False # #leptonic W pt cut event.mu = event.muons[0] event.leptonicW = event.mu.p4() + event.met.p4() if event.leptonicW.Pt() < 250.0: return False ## b-tag AK4 jet selection event.ak4jets = [] for j in event._allJets: if not (j.pt > 25.0 and abs(j.eta) < 2.4 and (j.jetId & 2)): continue if j.btagCSVV2 > 0.8484 and\ abs(deltaPhi(j, event.muons[0])) < 2.0: event.ak4jets.append(j) if len(event.ak4jets) < 1: return False # # selection on AK8 jets event.ak8jets = [] for fj in event._allAK8jets: if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)): continue if abs(deltaPhi(fj, event.muons[0])) > 2.0: event.ak8jets.append(fj) if len(event.ak8jets) < 1: return False # # selection on CA15 jets event.ca15jets = [] for fj in event._allCA15jets: if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)): continue if abs(deltaPhi(fj, event.muons[0])) > 2.0: event.ca15jets.append(fj) if len(event.ca15jets) < 1: return False ## require the leading ak8 & ca15 jets overlap if deltaR(event.ak8jets[0], event.ca15jets[0]) > 0.8: return False # # selection on HOTVR jets event.hotvrjets = [] for fj in event._allHOTVRjets: if not (fj.pt > 200 and abs(fj.eta) < 2.4): continue if abs(deltaPhi(fj, event.muons[0])) > 2.0: event.hotvrjets.append(fj) ## return True if passes selection return True
def prepareEvent(self, event): logging.debug('processing event %d' % event.event) ## select leading photon event._allPhotons = Collection(event, "Photon") event.photons = [] for pho in event._allPhotons: if not (pho.pt > 200 and abs(pho.eta) < 2.4 and (pho.cutBasedBitmap & 2) and pho.electronVeto): # medium ID continue event.photons.append(pho) if len(event.photons) < 1: return False ## selection on AK8 jets / drop if overlaps with a photon event.fatjets = [] for fj in event._allFatJets: if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)): continue # require jet and photon to be back-to-back if deltaPhi(event.photons[0], fj) < 2: continue # if deltaR(event.photons[0], fj) < self._jetConeSize: # continue event.fatjets.append(fj) if len(event.fatjets) < 1: return False ## selection on SV event._allSV = Collection(event, "SV") event.secondary_vertices = [] for sv in event._allSV: # if sv.ntracks > 2 and abs(sv.dxy) < 3. and sv.dlenSig > 4: # if sv.dlenSig > 4: if True: event.secondary_vertices.append(sv) if len(event.secondary_vertices) < 2: return False event.secondary_vertices = sorted(event.secondary_vertices, key=lambda x: x.pt, reverse=True) # sort by pt # event.secondary_vertices = sorted(event.secondary_vertices, key=lambda x : x.dxySig, reverse=True) # sort by dxysig # selection on the probe jet (sub-leading in pT) probe_fj = event.fatjets[0] if not (probe_fj.pt > 200 and probe_fj.msoftdrop > 50 and probe_fj.msoftdrop < 200): return False # require at least 1 SV matched to each subjet self.matchSVToSubjets(event, probe_fj) if len(probe_fj.subjets[0].sv_list) == 0 or len(probe_fj.subjets[1].sv_list) == 0: return False ## ht event.ak4jets = [] for j in event._allJets: if not (j.pt > 25 and abs(j.eta) < 2.4 and (j.jetId & 2)): continue event.ak4jets.append(j) event.ht = sum([j.pt for j in event.ak4jets]) ## return True if passes selection return True
def transverseMass(lepPt, lepPhi, met, metPhi): cosDPhi = cos(deltaPhi(lepPhi, metPhi)) return sqrt(2 * lepPt * met * (1 - cosDPhi))
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" if not (event.HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ or event.HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_DZ or event.HLT_IsoTkMu24 or event.HLT_IsoMu24): self.out.fillBranch("pass_selection",0) return True electrons = Collection(event, "Electron") muons = Collection(event, "Muon") jets = Collection(event, "Jet") Z = ROOT.TLorentzVector() tight_muons = [] if (len(muons)<=1): self.out.fillBranch("pass_selection",0) return True for i in range(0,len(muons)): if (muons[i].eta) < 2.4 and (muons[i].mediumId) and (muons[i].pfIsoId)>=3: if (muons[i].pt) <= 25: continue for j in range(i+1,len(muons)): if (muons[j].eta) < 2.4 and (muons[j].mediumId) and (muons[j].pfIsoId)>=3: if (muons[j].pt) <= 20: continue if (muons[i].charge + muons[j].charge == 0): Z = muons[i].p4() + muons[j].p4() if (Z.M() > 76 and Z.M() < 106): self.out.fillBranch("pass_selection",1) self.out.fillBranch("z_pt",Z.Pt()) self.out.fillBranch("z_mass",Z.M()) self.out.fillBranch("z_phi",Z.Phi()) tight_muons.append(i) tight_muons.append(j) #return True #print(2) if len(tight_muons) < 2: self.out.fillBranch("pass_selection",0) return True #print(3) njet = 0 for k in range(0,len(jets)): #print(4) if abs(jets[k].eta) > 2.4: jets[k].pt = -1000 jets[k].phi = -1000 jets[k].jetId = -1000 continue #print(5) if jets[k].pt < 30: jets[k].pt = -1000 jets[k].phi = -1000 jets[k].jetId = -1000 continue #print(6) if not (jets[k].jetId & 1): jets[k].pt = -1000 jets[k].phi = -1000 jets[k].jetId = -1000 continue #print(7) pass_lepton_dr_cut = True for i in range(0,len(tight_muons)): if deltaR(muons[tight_muons[i]].eta,muons[tight_muons[i]].phi,jets[k].eta,jets[k].phi) < 0.4: pass_lepton_dr_cut = False if not pass_lepton_dr_cut: jets[k].pt = -1000 jets[k].phi = -1000 jets[k].jetId = -1000 continue njet += 1 self.out.fillBranch("jet_pt",jets[k].pt) self.out.fillBranch("jet_id",jets[k].jetId) self.out.fillBranch("jet_phi",jets[k].phi) self.out.fillBranch("dphi_zjet",deltaPhi(Z.Phi(),jets[k].phi)) self.out.fillBranch("njet",njet) ''' if(njet!=0): print(njet) ''' return True
def analyze(self, event): """ process event, return True (go to next module) or False (fail, go to next event) """ # skip useless events if event.lep_category <= 0: return False # Get collection from event tree electrons = list(Collection(event, "Electron")) muons = list(Collection(event, "Muon")) jets = list(Collection(event, "Jet")) # in case of systematic take the shifted values are default # For the central values, need to include jetMetTool all the time # Jet systematics if self.syst_var == "": syst_var = "nom" else: syst_var = self.syst_var # checking something try: var_jet_pts = getattr(event, "Jet_pt_{}".format(syst_var), None) if var_jet_pts: for i, jet in enumerate(jets): jet.pt = var_jet_pts[i] else: print 'WARNING: jet pts with variation {}' 'not available, using the nominal value'.format(syst_var) except: var_jet_pts = getattr(event, "Jet_pt_nom", None) for i, jet in enumerate(jets): jet.pt = var_jet_pts[i] # Get variables from event tree Z_pt = event.Z_pt Z_eta = event.Z_eta Z_phi = event.Z_phi Z_mass = event.Z_mass Z_p4 = ROOT.TLorentzVector() Z_p4.SetPtEtaPhiM(Z_pt, Z_eta, Z_phi, Z_mass) Z_p4_bst = ROOT.TLorentzVector(Z_p4) met_pt = event.met_pt met_phi = event.met_phi met_p4 = ROOT.TLorentzVector() met_p4.SetPtEtaPhiM(met_pt, 0., met_phi, 0.) met_p4_bst = ROOT.TLorentzVector(met_p4) emulatedMET_pt_bst = event.emulatedMET emulatedMET_phi = event.emulatedMET_phi emulatedMET_p4 = ROOT.TLorentzVector() emulatedMET_p4.SetPtEtaPhiM(emulatedMET_pt_bst, 0., emulatedMET_phi, 0.) emulatedMET_p4_bst = ROOT.TLorentzVector(emulatedMET_p4) # process leptons good_leptons = [] good_muons = [] good_electrons = [] # Choose tight-quality e/mu for event categorization for idx, mu in enumerate(muons): isoLep = mu.pfRelIso04_all pass_ips = abs(mu.dxy) < 0.02 and abs(mu.dz) < 0.1 pass_fid = abs(mu.eta) < 2.4 and mu.pt >= (25 if idx == 0 else 20) pass_ids = mu.tightId and isoLep <= 0.15 if pass_fid and pass_ids and pass_ips: good_muons.append(mu) for idy, el in enumerate(electrons): if el.pt >= (25 if idy == 0 else 20) and abs( el.eta) <= 2.5 and self.electron_id(el, "90"): good_electrons.append(el) # Find any remaining e/mu that pass looser selection extra_leptons = [] for mu in muons: isoLep = mu.pfRelIso04_all pass_ids = mu.softId and isoLep <= 0.25 pass_fid = abs(mu.eta) < 2.4 and mu.pt >= 10 if tk.closest(mu, good_muons)[1] < 0.01: continue if pass_fid and pass_ids: extra_leptons.append(mu) for el in electrons: pass_fid = abs(el.eta) < 2.5 and el.pt >= 10 if tk.closest(el, good_electrons)[1] < 0.01: continue if pass_fid and self.electron_id(el, "WPL"): extra_leptons.append(el) # sort the leptons in pt good_muons.sort(key=lambda x: x.pt, reverse=True) good_electrons.sort(key=lambda x: x.pt, reverse=True) good_leptons = good_electrons + good_muons good_leptons.sort(key=lambda x: x.pt, reverse=True) extra_leptons.sort(key=lambda x: x.pt, reverse=True) ngood_leptons = len(good_leptons) nextra_leptons = len(extra_leptons) if ngood_leptons != event.ngood_leptons or nextra_leptons != event.nextra_leptons: print( 'n good (extra) leptons: {} ({}) in VBSProducer, {} ({}) in MonoZProducer.' .format(ngood_leptons, nextra_leptons, event.ngood_leptons, event.nextra_leptons)) lead_lep_p4 = good_leptons[0].p4( ) if ngood_leptons else ROOT.TLorentzVector(0., 0., 0., 0.) lead_lep_p4_bst = ROOT.TLorentzVector(lead_lep_p4) lead_lep_pt = good_leptons[0].pt if ngood_leptons else 0. trail_lep_p4 = good_leptons[1].p4( ) if ngood_leptons >= 2 else ROOT.TLorentzVector(0., 0., 0., 0.) trail_lep_p4_bst = ROOT.TLorentzVector(trail_lep_p4) trail_lep_pt = good_leptons[1].pt if ngood_leptons >= 2 else 0. # process jet good_jets = [] good_jets_p4 = ROOT.TLorentzVector(0., 0., 0., 0.) et_jets20 = 0. et_jets30 = 0. for jet in jets: if not jet.jetId: continue if tk.closest(jet, good_leptons)[1] < 0.4: continue if jet.pt <= 20 or abs(jet.eta) > 4.7: continue et_jets20 += jet.p4().Et() if jet.pt < 30.: continue et_jets30 += jet.p4().Et() good_jets.append(jet) good_jets_p4 += jet.p4() # sort the jets by pt good_jets.sort(key=lambda jet: jet.pt, reverse=True) ngood_jets = len(good_jets) if ngood_jets != event.ngood_jets: print 'ngood_jets: {} in VBSProducer, {} in MonoZProducer'.format( ngood_jets, event.ngood_jets) lead_jet_p4 = good_jets[0].p4() if ngood_jets else ROOT.TLorentzVector( 0., 0., 0., 0.) lead_jet_pt = good_jets[0].pt if ngood_jets else 0. lead_jet_phi = good_jets[0].phi if ngood_jets else 0. lead_jet_eta = good_jets[0].eta if ngood_jets else -99. trail_jet_p4 = good_jets[1].p4( ) if ngood_jets > 1 else ROOT.TLorentzVector(0., 0., 0., 0.) trail_jet_pt = good_jets[1].pt if ngood_jets > 1 else 0. trail_jet_phi = good_jets[1].phi if ngood_jets > 1 else 0. trail_jet_eta = good_jets[1].eta if ngood_jets > 1 else -99. # boosting 4 vectors boost_vet = good_jets_p4.BoostVector() lead_lep_p4_bst.Boost(boost_vet) trail_lep_p4_bst.Boost(boost_vet) Z_p4_bst.Boost(boost_vet) met_p4_bst.Boost(boost_vet) emulatedMET_p4_bst.Boost(boost_vet) # variables in bossted frame delta_eta_ll_bst = abs(lead_lep_p4_bst.Eta() - trail_lep_p4_bst.Eta()) delta_phi_ll_bst = tk.deltaPhi(lead_lep_p4_bst.Phi(), trail_lep_p4_bst.Phi()) delta_phi_ZMet_bst = tk.deltaPhi(Z_p4_bst.Phi(), met_p4_bst.Phi()) # more variables x_denom20 = (et_jets20 + met_pt + Z_pt) x_denom30 = (et_jets30 + met_pt + Z_pt) x_Z = Z_pt / x_denom30 if x_denom30 > 0. else -99. x_jet20 = et_jets20 / x_denom20 if x_denom20 > 0. else -99. x_jet30 = et_jets30 / x_denom30 if x_denom30 > 0. else -99. x_MET = met_pt / x_denom30 if x_denom30 > 0. else -99. H_T = sum([jet.pt for jet in good_jets]) HT_F = (lead_jet_pt + trail_jet_pt) / H_T if H_T > 0. else 0. Jet_etas_multiplied = lead_jet_eta * trail_jet_eta # more variables if ngood_jets >= 2: S_T_jets = (lead_jet_p4 + trail_jet_p4).Pt() / (lead_jet_pt + trail_jet_pt) S_T_hard = (lead_jet_p4 + trail_jet_p4 + Z_p4).Pt() / (lead_jet_pt + trail_jet_pt + Z_pt) S_T_all = (lead_jet_p4 + trail_jet_p4 + Z_p4 + met_p4).Pt() / ( lead_jet_pt + trail_jet_pt + Z_pt + met_pt) Jet_pt_Ratio = trail_jet_pt / lead_jet_pt R_pt = lead_lep_pt * trail_lep_pt / (lead_jet_pt * trail_jet_pt) dijet_abs_dEta = abs(lead_jet_eta - trail_jet_eta) dijet_Mjj = (lead_jet_p4 + trail_jet_p4).M() dijet_Zep = Z_eta - 0.5 * (lead_jet_eta + trail_jet_eta) dijet_centrality = np.exp(-4 * (dijet_Zep / dijet_abs_dEta)** 2) if dijet_abs_dEta > 0 else -99. # study jets between leading and trailing jets eta_range = sorted([lead_jet_eta, trail_jet_eta]) pT_mid_Jets = [ jet.pt for jet in good_jets[2:] if eta_range[0] < jet.eta < eta_range[1] ] CJV_Pt = pT_mid_Jets[0] if len(pT_mid_Jets) else 0. CJV_Pt_Sum = sum(pT_mid_Jets) if len(pT_mid_Jets) else 0. else: S_T_jets = -99. S_T_hard = -99. S_T_all = -99. Jet_pt_Ratio = -99. R_pt = -99. dijet_abs_dEta = -99. dijet_Mjj = -99. dijet_Zep = -99. dijet_centrality = -99. CJV_Pt = 0. CJV_Pt_Sum = 0. # more variables dPT_OZ = (lead_jet_pt + trail_jet_pt) / Z_pt if Z_pt > 0. else -99. etaThirdJet = good_jets[2].eta if ngood_jets >= 3 else -99. deltaPhiClosestJetMet = 99. deltaPhiFarthestJetMet = -99. for jet in good_jets: if deltaPhiClosestJetMet > abs(tk.deltaPhi(jet.phi, met_phi)): deltaPhiClosestJetMet = abs(tk.deltaPhi(jet.phi, met_phi)) if deltaPhiFarthestJetMet < abs(tk.deltaPhi(jet.phi, met_phi)): deltaPhiFarthestJetMet = abs(tk.deltaPhi(jet.phi, met_phi)) self.out.fillBranch("lead_jet_eta{}".format(self.syst_suffix), lead_jet_eta) self.out.fillBranch("lead_jet_phi{}".format(self.syst_suffix), lead_jet_phi) self.out.fillBranch("trail_jet_pt{}".format(self.syst_suffix), trail_jet_pt) self.out.fillBranch("trail_jet_eta{}".format(self.syst_suffix), trail_jet_eta) self.out.fillBranch("trail_jet_phi{}".format(self.syst_suffix), trail_jet_phi) self.out.fillBranch("dijet_abs_dEta{}".format(self.syst_suffix), dijet_abs_dEta) self.out.fillBranch("dijet_Mjj{}".format(self.syst_suffix), dijet_Mjj) self.out.fillBranch("dijet_Zep{}".format(self.syst_suffix), dijet_Zep) self.out.fillBranch("dijet_centrality{}".format(self.syst_suffix), dijet_centrality) self.out.fillBranch("S_T_hard{}".format(self.syst_suffix), S_T_hard) self.out.fillBranch("S_T_jets{}".format(self.syst_suffix), S_T_jets) self.out.fillBranch("S_T_all{}".format(self.syst_suffix), S_T_all) self.out.fillBranch("x_Z{}".format(self.syst_suffix), x_Z) self.out.fillBranch("x_jet20{}".format(self.syst_suffix), x_jet20) self.out.fillBranch("x_jet30{}".format(self.syst_suffix), x_jet30) self.out.fillBranch("x_MET{}".format(self.syst_suffix), x_MET) self.out.fillBranch("H_T{}".format(self.syst_suffix), H_T) self.out.fillBranch("HT_F{}".format(self.syst_suffix), HT_F) self.out.fillBranch("Jet_pt_Ratio{}".format(self.syst_suffix), Jet_pt_Ratio) self.out.fillBranch("R_pt{}".format(self.syst_suffix), R_pt) self.out.fillBranch("Jet_etas_multiplied{}".format(self.syst_suffix), Jet_etas_multiplied) self.out.fillBranch("dPT_OZ{}".format(self.syst_suffix), dPT_OZ) self.out.fillBranch("CJV_Pt{}".format(self.syst_suffix), CJV_Pt) self.out.fillBranch("CJV_Pt_Sum{}".format(self.syst_suffix), CJV_Pt_Sum) self.out.fillBranch("deltaPhiClosestJetMet{}".format(self.syst_suffix), deltaPhiClosestJetMet) self.out.fillBranch( "deltaPhiFarthestJetMet{}".format(self.syst_suffix), deltaPhiFarthestJetMet) self.out.fillBranch("etaThirdJet{}".format(self.syst_suffix), etaThirdJet) self.out.fillBranch("Z_pt_bst{}".format(self.syst_suffix), Z_p4_bst.Pt()) self.out.fillBranch("Z_phi_bst{}".format(self.syst_suffix), Z_p4_bst.Phi()) self.out.fillBranch("met_pt_bst{}".format(self.syst_suffix), met_p4_bst.Pt()) self.out.fillBranch("met_phi_bst{}".format(self.syst_suffix), met_p4_bst.Phi()) self.out.fillBranch("emulatedMET_pt_bst{}".format(self.syst_suffix), emulatedMET_p4_bst.Pt()) self.out.fillBranch("emulatedMET_phi_bst{}".format(self.syst_suffix), emulatedMET_p4_bst.Phi()) self.out.fillBranch("delta_phi_ll_bst{}".format(self.syst_suffix), delta_phi_ll_bst) self.out.fillBranch("delta_eta_ll_bst{}".format(self.syst_suffix), delta_eta_ll_bst) self.out.fillBranch("delta_phi_ZMet_bst{}".format(self.syst_suffix), delta_phi_ZMet_bst) return True