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 analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" leptonSel(event) for elect in event.allelectrons: self.h_eCorr_vs_eta.Fill(elect.eCorr, elect.eta) self.h_eCorr_vs_phi.Fill(elect.eCorr, elect.phi) self.h_eCorr_vs_pt.Fill(elect.eCorr, elect.pt) Jets = Collection(event, "Jet") met = Object(event, "MET") genmet = Object(event, "GenMET") if self.isMC or self.isSig: Gen = Collection(event, "GenPart") event.genleps = [ l for l in Gen if abs(l.pdgId) == 11 or abs(l.pdgId) == 13 ] GenTau = Collection(event, "GenVisTau") event.gentauleps = [l for l in GenTau] goodLep = [l for l in event.selectedLeptons] LepOther = [l for l in event.otherLeptons] self.out.fillBranch("nLepGood", len(goodLep)) self.out.fillBranch("nLepOther", len(LepOther)) #LepOther = goodLep leps = goodLep nlep = len(leps) # adding the ST HT filter if nlep > 0: ST1 = leps[0].pt + met.pt self.out.fillBranch("ST1", ST1) HT1 = sum([j.pt for j in Jets if (j.pt > 30 and abs(j.eta) < 2.4)]) self.out.fillBranch("HT1", HT1) ### LEPTONS Selected = False if self.isMC == False and self.isSig == False: self.out.fillBranch("isData", 1) else: self.out.fillBranch("isData", 0) # selected good leptons selectedTightLeps = [] selectedTightLepsIdx = [] selectedVetoLeps = [] # anti-selected leptons antiTightLeps = [] antiTightLepsIdx = [] antiVetoLeps = [] for idx, lep in enumerate(leps): # for acceptance check lepEta = abs(lep.eta) # Pt cut if lep.pt < 10: continue # Iso cut -- to be compatible with the trigger if lep.miniPFRelIso_all > trig_miniIsoCut: continue ################### # MUONS ################### if (abs(lep.pdgId) == 13): if lepEta > 2.4: continue ## Lower ID is POG_LOOSE (see cfg) # ID, IP and Iso check: passID = False #if muID=='ICHEPmediumMuonId': passID = lep.ICHEPmediumMuonId -->> not needed any more passID = lep.mediumId passIso = lep.miniPFRelIso_all < muo_miniIsoCut passIP = lep.sip3d < goodMu_sip3d # selected muons if passID and passIso and passIP: selectedTightLeps.append(lep) selectedTightLepsIdx.append(idx) antiVetoLeps.append(lep) else: selectedVetoLeps.append(lep) # anti-selected muons if not passIso: antiTightLeps.append(lep) antiTightLepsIdx.append(idx) else: antiVetoLeps.append(lep) ################### # ELECTRONS ################### elif (abs(lep.pdgId) == 11): if lepEta > eleEta: continue # pass variables passIso = False passConv = False if eleID == 'CB': # ELE CutBased ID eidCB = lep.cutBased passTightID = ( eidCB == 4 ) # and abs(lep.dxy) < 0.05 and abs(lep.dz) < 0.1) # and lep.convVeto) passMediumID = ( eidCB >= 3 ) # and abs(lep.dxy) < 0.05 and abs(lep.dz) < 0.1)# and lep.convVeto) #passLooseID = (eidCB >= 2) passVetoID = ( eidCB >= 1 ) # and abs(lep.dxy) < 0.2 and abs(lep.dz) < 0.5) # and lep.convVeto) # selected if passTightID: # all tight leptons are veto for anti antiVetoLeps.append(lep) # Iso check: if lep.miniPFRelIso_all < ele_miniIsoCut: passIso = True # conversion check elif eleID == 'CB': passConv = True #if lep.lostHits <= goodEl_lostHits and lep.convVeto and lep.sip3d < goodEl_sip3d else False # cuts already included in POG_Cuts_ID_SPRING15_25ns_v1_ConvVetoDxyDz_X passPostICHEPHLTHOverE = True #if (lep.hoe < 0.04 and abs(lep.eta)>1.479) or abs(lep.eta)<=1.479 else False # fill if passIso and passConv and passPostICHEPHLTHOverE: selectedTightLeps.append(lep) selectedTightLepsIdx.append(idx) else: selectedVetoLeps.append(lep) # anti-selected elif not passMediumID: #passVetoID: # all anti leptons are veto for selected selectedVetoLeps.append(lep) # Iso check passIso = lep.miniPFRelIso_all < Lep_miniIsoCut # should be true anyway # other checks passOther = False if hasattr(lep, "hoe"): passOther = lep.hoe > 0.01 # fill if passIso and passOther: antiTightLeps.append(lep) antiTightLepsIdx.append(idx) else: antiVetoLeps.append(lep) # Veto leptons elif passVetoID: # the rest is veto for selected and anti selectedVetoLeps.append(lep) antiVetoLeps.append(lep) # end lepton loop ################### # EXTRA Loop for lepOther -- for anti-selected leptons ################### otherleps = [ l for l in LepOther ] #(set(selectedTightLeps) or set(selectedVetoLeps) or set(antiTightLeps) or set(antiVetoLeps) )] nLepOther = len(otherleps) for idx, lep in enumerate(otherleps): # check acceptance lepEta = abs(lep.eta) if lepEta > 2.4: continue # Pt cut if lep.pt < 10: continue # Iso cut -- to be compatible with the trigger if lep.miniPFRelIso_all > trig_miniIsoCut: continue ############ # Muons if (abs(lep.pdgId) == 13): ## Lower ID is POG_LOOSE (see cfg) # ID, IP and Iso check: passIso = lep.miniPFRelIso_all > muo_miniIsoCut #if passIso and passID and passIP: if passIso: antiTightLeps.append(lep) antiTightLepsIdx.append(idx) else: antiVetoLeps.append(lep) ############ # Electrons elif (abs(lep.pdgId) == 11): if (lepEta > eleEta): continue ## Iso selection: ele should have MiniIso < 0.4 (for trigger) if lep.miniPFRelIso_all > Lep_miniIsoCut: continue ## Set Ele IDs if eleID == 'CB': # ELE CutBased ID eidCB = lep.cutBased passMediumID = ( eidCB >= 3 ) # and lep.convVeto and abs(lep.dxy) < 0.05 and abs(lep.dz) < 0.1) passVetoID = ( eidCB >= 1 ) #and lep.convVeto and abs(lep.dxy) < 0.05 and abs(lep.dz) < 0.1) else: passMediumID = False passVetoID = False # Cuts for Anti-selected electrons if not passMediumID: # should always be true for LepOther # other checks passOther = False if hasattr(lep, "hoe"): passOther = lep.hoe > 0.01 #if not lep.conVeto: if passOther: antiTightLeps.append(lep) antiTightLepsIdx.append(idx) else: antiVetoLeps.append(lep) elif passVetoID: #all Medium+ eles in LepOther antiVetoLeps.append(lep) ############# ############# # retrive and fill branches ############# # choose common lepton collection: select selected or anti lepton if len(selectedTightLeps) > 0: tightLeps = selectedTightLeps tightLepsIdx = selectedTightLepsIdx vetoLeps = selectedVetoLeps self.out.fillBranch("nTightLeps", len(tightLeps)) self.out.fillBranch( "nTightMu", sum([abs(lep.pdgId) == 13 for lep in tightLeps])) self.out.fillBranch( "nTightEl", sum([abs(lep.pdgId) == 11 for lep in tightLeps])) self.out.fillBranch("tightLepsIdx", tightLepsIdx) self.out.fillBranch("Selected", 1) # Is second leading lepton selected, too? if len(selectedTightLeps) > 1: self.out.fillBranch("Selected2", 1) else: self.out.fillBranch("Selected2", 0) elif len(antiTightLeps) > 0: tightLeps = antiTightLeps tightLepsIdx = antiTightLepsIdx vetoLeps = antiVetoLeps self.out.fillBranch("nTightLeps", 0) self.out.fillBranch("nTightMu", 0) self.out.fillBranch("nTightEl", 0) self.out.fillBranch("tightLepsIdx", []) self.out.fillBranch("Selected", -1) else: tightLeps = [] tightLepsIdx = [] vetoLeps = [] self.out.fillBranch("nTightLeps", 0) self.out.fillBranch("nTightMu", 0) self.out.fillBranch("nTightEl", 0) self.out.fillBranch("tightLepsIdx", []) self.out.fillBranch("Selected", 0) # store Tight and Veto lepton numbers self.out.fillBranch("nLep", len(tightLeps)) self.out.fillBranch("nVeto", len(vetoLeps)) # get number of tight el and mu tightEl = [lep for lep in tightLeps if abs(lep.pdgId) == 11] tightMu = [lep for lep in tightLeps if abs(lep.pdgId) == 13] VetoEl = [lep for lep in vetoLeps if abs(lep.pdgId) == 11] VetoMu = [lep for lep in vetoLeps if abs(lep.pdgId) == 13] self.out.fillBranch("nEl", len(tightEl)) self.out.fillBranch("nMu", len(tightMu)) for El in tightEl: # this branch is for investigating the electron energy calibraition self.out.fillBranch("TightEl_eCorr", El.eCorr) self.h_eCorr_vs_eta_tight.Fill(El.eCorr, El.eta) self.h_eCorr_vs_phi_tight.Fill(El.eCorr, El.phi) self.h_eCorr_vs_pt_tight.Fill(El.eCorr, El.pt) for El in VetoEl: self.h_eCorr_vs_eta_veto.Fill(El.eCorr, El.eta) self.h_eCorr_vs_phi_veto.Fill(El.eCorr, El.phi) self.h_eCorr_vs_pt_veto.Fill(El.eCorr, El.pt) # save leading lepton vars if len(tightLeps) > 0: # leading tight lep self.out.fillBranch("Lep_Idx", tightLepsIdx[0]) self.out.fillBranch("Lep_pt", tightLeps[0].pt) self.out.fillBranch("Lep_eta", tightLeps[0].eta) self.out.fillBranch("Lep_phi", tightLeps[0].phi) self.out.fillBranch("Lep_pdgId", tightLeps[0].pdgId) self.out.fillBranch("Lep_relIso", tightLeps[0].pfRelIso03_all) self.out.fillBranch("Lep_miniIso", tightLeps[0].miniPFRelIso_all) if hasattr(tightLeps[0], "hoe"): self.out.fillBranch("Lep_hOverE", tightLeps[0].hoe) if self.isMC: for tlep in tightLeps: if abs(tlep.pdgId) == 13: sf_mu = self._worker_mu.getSF(tlep.pdgId, tlep.pt, tlep.eta) self.out.fillBranch("lepSF", sf_mu) self.out.fillBranch("Muon_effSF", sf_mu) elif abs(tlep.pdgId) == 11: sf_el = self._worker_el.getSF(tlep.pdgId, tlep.pt, tlep.eta) self.out.fillBranch("lepSF", sf_el) self.out.fillBranch("Electron_effSF", sf_el) else: self.out.fillBranch("Muon_effSF", 1.0) self.out.fillBranch("Electron_effSF", 1.0) self.out.fillBranch("lepSF", 1.0) else: self.out.fillBranch("Muon_effSF", 1.0) self.out.fillBranch("Electron_effSF", 1.0) self.out.fillBranch("lepSF", 1.0) elif len(leps) > 0: # fill it with leading lepton self.out.fillBranch("Lep_Idx", 0) self.out.fillBranch("Lep_pt", leps[0].pt) self.out.fillBranch("Lep_eta", leps[0].eta) self.out.fillBranch("Lep_phi", leps[0].phi) self.out.fillBranch("Lep_pdgId", leps[0].pdgId) self.out.fillBranch("Lep_relIso", leps[0].pfRelIso03_all) self.out.fillBranch("Lep_miniIso", leps[0].miniPFRelIso_all) if hasattr(leps[0], "hoe"): self.out.fillBranch("Lep_hOverE", leps[0].hoe) # save second leading lepton vars if len(tightLeps) > 1: # 2nd tight lep self.out.fillBranch("Lep2_pt", tightLeps[1].pt) # print " Nlep : ", len(leps) , " nTightleps " , len(tightLeps), " nVetoLEp ", len(vetoLeps) ##################################################################### ##################################################################### #################Jets, BJets, METS and filters ###################### ##################################################################### ##################################################################### ######## ### Jets ######## metp4 = ROOT.TLorentzVector(0, 0, 0, 0) Genmetp4 = ROOT.TLorentzVector(0, 0, 0, 0) if self.isMC: Genmetp4.SetPtEtaPhiM(genmet.pt, 0, genmet.phi, 0) #self.out.fillBranch("MET", metp4.Pt()) Jets = Collection(event, "Jet") jets = [j for j in Jets if j.pt > 20 and abs(j.eta) < 2.4] njet = len(jets) (met_px, met_py) = (met.pt * math.cos(met.phi), met.pt * math.sin(met.phi)) (met_px_nom, met_py_nom) = (met_px, met_py) # match reconstructed jets to generator level ones # (needed to evaluate JER scale factors and uncertainties) if self.isMC and self.CorrMET: rho = getattr(event, "fixedGridRhoFastjetAll") genJets = Collection(event, "GenJet") pairs = matchObjectCollection(Jets, genJets) for jet in jets: genJet = pairs[jet] (jet_pt_jerNomVal, jet_pt_jerUpVal, jet_pt_jerDownVal) = self.jetSmearer.getSmearValsPt( jet, genJet, rho) # exclude this from the JECs correction to follow the SUSY recipe, well see if it will slove the prefire issue if self.era == "2017": if jet.pt < 75 and (2.0 < abs(jet.eta) < 3.0): jet_pt = jet.pt * (1. - jet.rawFactor) else: jet_pt = self.jetReCalibrator.correct(jet, rho) else: jet_pt = jet.pt jet_pt_nom = jet_pt_jerNomVal * jet_pt if jet_pt_nom < 0.0: jet_pt_nom *= -1.0 jet_pt_jerUp = jet_pt_jerUpVal * jet_pt jet_pt_jerDown = jet_pt_jerDownVal * jet_pt # recalculate the MET after applying the JEC JER if jet_pt > 15.: jet_cosPhi = math.cos(jet.phi) jet_sinPhi = math.sin(jet.phi) met_px_nom = met_px_nom - (jet_pt_nom - jet_pt) * jet_cosPhi met_py_nom = met_py_nom - (jet_pt_nom - jet_pt) * jet_sinPhi met_pt_nom = math.sqrt(met_px_nom**2 + met_py_nom**2) met_phi_nom = math.atan2(met_py_nom, met_px_nom) met.pt = met_pt_nom met.phi = met_phi_nom # JECs already applied so apply only JER jet.pt = jet_pt_jerNomVal * jet.pt if jet.pt < 0.0: jet.pt *= -1.0 metp4.SetPtEtaPhiM( met.pt, 0., met.phi, 0.) # only use met vector to derive transverse quantities) self.out.fillBranch("Met", met.pt) centralJet30 = [] centralJet30idx = [] centralJet40 = [] cleanJets25 = [] cleanJets25idx = [] cleanJets = [] cleanJetsidx = [] # fill this flage but defults to 1 and then change it after the proper selection self.out.fillBranch("Flag_fastSimCorridorJetCleaning", 1) for i, j in enumerate(jets): # Cleaning up of fastsim jets (from "corridor" studies) https://twiki.cern.ch/twiki/bin/viewauth/CMS/SUSRecommendationsMoriond17#Cleaning_up_of_fastsim_jets_from if self.isSig: #only check for signals (see condition check above) self.out.fillBranch("isDPhiSignal", 1) genj = pairs[j] if genj is not None: if j.pt > 20 and abs( j.eta) < 2.5 and (genj.pt == 0) and j.chHEF < 0.1: self.out.fillBranch("Flag_fastSimCorridorJetCleaning", 0) if j.pt > 25: cleanJets25.append(j) cleanJets25idx.append(j) if j.pt > 30 and abs(j.eta) < centralEta: centralJet30.append(j) centralJet30idx.append(i) if j.pt > 40 and abs(j.eta) < centralEta: centralJet40.append(j) # jets 30 (cmg cleaning only) nJetC = len(centralJet30) self.out.fillBranch("nJets", nJetC) self.out.fillBranch("nJets30", nJetC) # store indeces self.out.fillBranch("Jets30Idx", centralJet30idx) #print "nJets30:", len(centralJet30), " nIdx:", len(centralJet30idx) # jets 40 nJet40C = len(centralJet40) self.out.fillBranch("nJets40", nJet40C) ############################## ## Local cleaning from leptons ############################## cJet30Clean = [] dRminCut = 0.4 # Do cleaning a la CMG: clean max 1 jet for each lepton (the nearest) cJet30Clean = centralJet30 cleanJets30 = centralJet30 #clean selected leptons at First '''for lep in goodLep: if lep.pt < 20 : continue jNear, dRmin = None, 99 # find nearest jet for jet in centralJet30: dR = jet.p4().DeltaR(lep.p4()) if dR < dRmin: jNear, dRmin = jet, dR # remove nearest jet if dRmin < dRminCut: cJet30Clean.remove(jNear)''' #then clean other tight leptons for lep in tightLeps: # don't clean LepGood, only LepOther #if lep not in otherleps: continue jNear, dRmin = None, 99 # find nearest jet for jet in centralJet30: dR = jet.p4().DeltaR(lep.p4()) if dR < dRmin: jNear, dRmin = jet, dR # remove nearest jet if dRmin < dRminCut: cJet30Clean.remove(jNear) for ijet, jet25 in enumerate(cleanJets25): dR = jet25.p4().DeltaR(lep.p4()) if dR < dRmin: cleanJets.append(jet25) cleanJetsidx.append(ijet) # cleaned jets nJet30C = len(cJet30Clean) self.out.fillBranch("nJets30Clean", len(cJet30Clean)) if nJet30C > 0: self.out.fillBranch("Jet1_pt", cJet30Clean[0].pt) self.out.fillBranch("Jet1_eta", cJet30Clean[0].eta) if nJet30C > 1: self.out.fillBranch("Jet2_pt", cJet30Clean[1].pt) self.out.fillBranch("Jet2_eta", cJet30Clean[1].eta) # imho, use Jet2_pt > 80 instead self.out.fillBranch( "LSLjetptGT80", 1 if sum([j.pt > 80 for j in cJet30Clean]) >= 2 else 0) self.out.fillBranch("htJet30j", sum([j.pt for j in cJet30Clean])) self.out.fillBranch("htJet30ja", sum([j.pt for j in jets if j.pt > 30])) self.out.fillBranch("htJet40j", sum([j.pt for j in centralJet40])) self.out.fillBranch("HT", sum([j.pt for j in cJet30Clean])) ## B tagging WPs for CSVv2 (CSV-IVF) ## from: https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideBTagging#Preliminary_working_or_operating # WP defined on top btagWP = self.btag_MediumWP btag_DeepMediumWP = self.btag_DeepMediumWP btag_LooseWP = self.btag_LooseWP BJetMedium30 = [] BJetMedium40 = [] nBJetDeep = 0 for i, j in enumerate(cJet30Clean): if j.btagCSVV2 > btagWP: BJetMedium30.append(j) if (j.btagDeepB) > btag_DeepMediumWP: nBJetDeep += 1 for i, j in enumerate(centralJet40): if j.btagCSVV2 > btagWP: BJetMedium40.append(j) # using cleaned collection! self.out.fillBranch("nBJet", len(BJetMedium30)) self.out.fillBranch("nBJets30", len(BJetMedium30)) self.out.fillBranch("nBJetDeep", nBJetDeep) # using normal collection self.out.fillBranch("nBJets40", len(BJetMedium40)) ###### # MET ##### ##################################################################### ##################################################################### #################High level variables ############################### ##################################################################### ##################################################################### dPhiLepW = -999 # set default value to -999 to spot "empty" entries GendPhiLepW = -999 # set default value to -999 to spot "empty" entries # LT of lepton and MET LT = -999 GenLT = -999 Lp = -99 MT = -99 if len(tightLeps) >= 1: recoWp4 = tightLeps[0].p4() + metp4 GenrecoWp4 = tightLeps[0].p4() + Genmetp4 GendPhiLepW = tightLeps[0].p4().DeltaPhi(GenrecoWp4) GenLT = tightLeps[0].pt + Genmetp4.Pt() dPhiLepW = tightLeps[0].p4().DeltaPhi(recoWp4) LT = tightLeps[0].pt + metp4.Pt() Lp = tightLeps[0].pt / recoWp4.Pt() * math.cos(dPhiLepW) #MT = recoWp4.Mt() # doesn't work MT = math.sqrt(2 * metp4.Pt() * tightLeps[0].pt * (1 - math.cos(dPhiLepW))) self.out.fillBranch("DeltaPhiLepW", dPhiLepW) dPhi = abs(dPhiLepW) # nickname for absolute dPhiLepW self.out.fillBranch("dPhi", dPhi) self.out.fillBranch("ST", LT) self.out.fillBranch("LT", LT) self.out.fillBranch("Lp", Lp) self.out.fillBranch("MT", MT) self.out.fillBranch("GendPhi", abs(GendPhiLepW)) self.out.fillBranch("GenLT", GenLT) self.out.fillBranch("GenMET", Genmetp4.Pt()) ##################### ## SIGNAL REGION FLAG ##################### ## Signal region flag # isSR SR vs CR flag isSR = 0 # 0-B SRs -- simplified dPhi if len(BJetMedium30) == 0: # check the no. of Bjets if LT < 250: isSR = 0 elif LT > 250: isSR = dPhi > 0.75 # BLIND data if (not self.isMC) and nJet30C >= 5: isSR = -isSR # Multi-B SRs elif nJet30C < 99: if LT < 250: isSR = 0 elif LT < 350: isSR = dPhi > 1.0 elif LT < 600: isSR = dPhi > 0.75 elif LT > 600: isSR = dPhi > 0.5 # BLIND data if (not self.isMC) and nJet30C >= 6: isSR = -isSR self.out.fillBranch("isSR", isSR) ############# ## Playground ############# # di-lepton mass: opposite-sign, same flavour Mll = 0 if len(tightLeps) > 1: lep1 = tightLeps[0] id1 = lep1.pdgId for lep2 in leps[1:]: if lep2.pdgId + lep1.pdgId == 0: dilepP4 = lep1.p4() + lep2.p4() Mll = dilepP4.M() self.out.fillBranch("Mll", Mll) # RA2 proposed filter self.out.fillBranch( "RA2_muJetFilter", True ) # normally true for now # don't know how to get the Muon energy fraction from EMEF #for j in cJet30Clean: # if j.pt > 200 and j.chEmEF > 0.5 and abs(math.acos(math.cos(j.phi-metp4.Phi()))) > (math.pi - 0.4): # self.out.fillBranch("RA2_muJetFilter", False) ## MET FILTERS for data looks like the met filters are applied already for nanoAOD ##################### ## Top Tagging ------->>>>>>. to be moved to different modules keep it commented here ##################### lightJets = [j for j in cleanJets if not j.btagCSVV2 == btagWP] bjetsLoose = [j for j in cleanJets if j.btagCSVV2 == btag_LooseWP] minMWjj = 999 minMWjjPt = 0 bestMWjj = 0 bestMWjjPt = 0 bestMTopHad = 0 bestMTopHadPt = 0 for i1, j1 in enumerate(lightJets): for i2 in xrange(i1 + 1, len(lightJets)): j2 = lightJets[i2] jjp4 = j1.p4() + j2.p4() mjj = jjp4.M() if mjj > 30 and mjj < minMWjj: minMWjj = mjj minMWjjPt = jjp4.Pt() self.out.fillBranch("minMWjj", minMWjj) self.out.fillBranch("minMWjjPt", minMWjjPt) if abs(mjj - 80.4) < abs(bestMWjj - 80.4): bestMWjj = mjj bestMWjjPt = jjp4.Pt() self.out.fillBranch("bestMWjj", bestMWjj) self.out.fillBranch("bestMWjjPt", bestMWjjPt) for bj in bjetsLoose: if deltaR(bj.eta(), bj.phi(), j1.eta(), j1.phi()) < 0.1 or deltaR( bj.eta(), bj.phi(), j2.eta(), j2.phi()) < 0.1: continue tp4 = jjp4 + bj.p4() mtop = tp4.M() if abs(mtop - 172) < abs(bestMTopHad - 172): bestMTopHad = mtop bestMTopHadPt = tp4.Pt() self.out.fillBranch("bestMTopHad", bestMTopHad) self.out.fillBranch("bestMTopHadPt", bestMTopHadPt) ##################################################################### ##################################################################### #################Fill MT2 here, not point to make a separate module## ##################################################################### ##################################################################### # isolated tracks after basic selection (((pt>5 && (abs(pdgId) == 11 || abs(pdgId) == 13)) || pt > 10) && (abs(pdgId) < 15 || abs(eta) < 2.5) && abs(dxy) < 0.2 && abs(dz) < 0.1 && ((pfIsolationDR03().chargedHadronIso < 5 && pt < 25) || pfIsolationDR03().chargedHadronIso/pt < 0.2)) and lepton veto # First check is the event has the IsoTrack or not if hasattr(event, "nIsoTrack"): trks = [j for j in Collection(event, "IsoTrack", "nIsoTrack")] tp4 = ROOT.TLorentzVector(0, 0, 0, 0) # min dR between good lep and iso track minDR = 0.1 # MT2 cuts for hadronic and leptonic veto tracks hadMT2cut = 60 lepMT2cut = 80 if (len(tightLeps) >= 1) and len(trks) >= 1: for i, t in enumerate(trks): # looking for opposite charged tracks #if tightLeps[0].charge == t.charge: continue # not track charge is founded replace with the next copule of lines if t.isHighPurityTrack == False: continue #print t.miniPFRelIso_chg # not track mass is founded tp4.SetPtEtaPhiM(t.pt, t.eta, t.phi, 0.) dR = tp4.DeltaR(tightLeps[0].p4()) if minDR > dR: continue p1 = tightLeps[0].p4() p2 = tp4 a = array.array('d', [p1.M(), p1.Px(), p1.Py()]) b = array.array('d', [p2.M(), p2.Px(), p2.Py()]) c = array.array('d', [metp4.M(), metp4.Px(), metp4.Py()]) mt2obj.set_momenta(a, b, c) mt2obj.set_mn(0) self.out.fillBranch("iso_MT2", mt2obj.get_mt2()) self.out.fillBranch("iso_pt", p2.Pt()) # cuts on MT2 as defined above if abs(t.pdgId) > 10 and abs(t.pdgId) < 14: self.out.fillBranch("iso_had", 0) #leptonic cut = lepMT2cut else: self.out.fillBranch("iso_had", 1) #hadronic track cut = hadMT2cut if mt2obj.get_mt2() <= cut: self.out.fillBranch("iso_Veto", True) self.out.fillBranch("Xsec", self.xs) if 'JetHT' in self.filename: self.out.fillBranch("PD_JetHT", True) else: self.out.fillBranch("PD_JetHT", False) if 'SingleEle' in self.filename: self.out.fillBranch("PD_SingleEle", True) else: self.out.fillBranch("PD_SingleEle", False) if 'SingleMu' in self.filename: self.out.fillBranch("PD_SingleMu", True) else: self.out.fillBranch("PD_SingleMu", False) if 'MET' in self.filename: self.out.fillBranch("PD_MET", True) else: self.out.fillBranch("PD_MET", False) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" allelectrons = Collection(event, "Electron") allmuons = Collection(event, "Muon") Jets = Collection(event, "Jet") met = Object(event, "MET") genmet = Object(event, "GenMET") # for all leptons (veto or tight) ### inclusive leptons = all leptons that could be considered somewhere in the analysis, with minimal requirements (used e.g. to match to MC) event.inclusiveLeptons = [] ### selected leptons = subset of inclusive leptons passing some basic id definition and pt requirement ### other leptons = subset of inclusive leptons failing some basic id definition and pt requirement event.selectedLeptons = [] event.selectedMuons = [] event.selectedElectrons = [] event.otherLeptons = [] inclusiveMuons = [] inclusiveElectrons = [] for mu in allmuons: if (mu.pt > 10 and abs(mu.eta) < 2.4 and abs(mu.dxy) < 0.5 and abs(mu.dz) < 1.): inclusiveMuons.append(mu) for ele in allelectrons: if ( ele.cutBased >= 1 and ele.pt > 10 and abs(ele.eta) < 2.4 ): # and abs(ele.dxy)<0.5 and abs(ele.dz)<1. and ele.lostHits <=1.0): inclusiveElectrons.append(ele) event.inclusiveLeptons = inclusiveMuons + inclusiveElectrons # make loose leptons (basic selection) for mu in inclusiveMuons: if (mu.pt > 10 and abs(mu.eta) < 2.4 and mu.miniPFRelIso_all < 0.4 and mu.isPFcand and abs(mu.dxy) < 0.05 and abs(mu.dz) < 0.5): event.selectedLeptons.append(mu) event.selectedMuons.append(mu) else: event.otherLeptons.append(mu) looseMuons = event.selectedLeptons[:] for ele in inclusiveElectrons: ele.looseIdOnly = ele.cutBased >= 1 if (ele.looseIdOnly and ele.pt > 10 and abs(ele.eta) < 2.4 and ele.miniPFRelIso_all < 0.4 and ele.isPFcand and ele.convVeto and # and abs(ele.dxy)<0.05 and abs(ele.dz)<0.5 and ele.lostHits <=1.0 and (bestMatch(ele, looseMuons)[1] > (0.05**2))): event.selectedLeptons.append(ele) event.selectedElectrons.append(ele) else: event.otherLeptons.append(ele) event.otherLeptons.sort(key=lambda l: l.pt, reverse=True) event.selectedLeptons.sort(key=lambda l: l.pt, reverse=True) event.selectedMuons.sort(key=lambda l: l.pt, reverse=True) event.selectedElectrons.sort(key=lambda l: l.pt, reverse=True) event.inclusiveLeptons.sort(key=lambda l: l.pt, reverse=True) goodLep = [l for l in event.selectedLeptons] LepOther = [l for l in event.otherLeptons] #LepOther = goodLep leps = goodLep nlep = len(leps) ### LEPTONS # selected good leptons selectedTightLeps = [] selectedTightLepsIdx = [] selectedVetoLeps = [] # anti-selected leptons antiTightLeps = [] antiTightLepsIdx = [] antiVetoLeps = [] for idx, lep in enumerate(leps): # for acceptance check lepEta = abs(lep.eta) # Pt cut if lep.pt < 10: continue # Iso cut -- to be compatible with the trigger if lep.miniPFRelIso_all > trig_miniIsoCut: continue ################### # MUONS ################### if (abs(lep.pdgId) == 13): if lepEta > 2.4: continue passID = lep.mediumId passIso = lep.miniPFRelIso_all < muo_miniIsoCut passIP = lep.sip3d < goodMu_sip3d # selected muons if passID and passIso and passIP: selectedTightLeps.append(lep) selectedTightLepsIdx.append(idx) antiVetoLeps.append(lep) else: selectedVetoLeps.append(lep) # anti-selected muons if not passIso: antiTightLeps.append(lep) antiTightLepsIdx.append(idx) else: antiVetoLeps.append(lep) ################### # ELECTRONS ################### elif (abs(lep.pdgId) == 11): if lepEta > eleEta: continue # pass variables passIso = False passConv = False if eleID == 'CB': # ELE CutBased ID eidCB = lep.cutBased passTightID = (eidCB == 4) # and lep.convVeto) passMediumID = (eidCB >= 3) # and lep.convVeto) #passLooseID = (eidCB >= 2) passVetoID = (eidCB >= 1) #and lep.convVeto) elif eleID == 'MVA': # ELE MVA ID # check MVA WPs passTightID = checkEleMVA(lep, 'Tight') passLooseID = checkEleMVA(lep, 'VLoose') # selected if passTightID: # all tight leptons are veto for anti antiVetoLeps.append(lep) # Iso check: if lep.miniPFRelIso_all < ele_miniIsoCut: passIso = True # conversion check if eleID == 'MVA': if lep.lostHits <= goodEl_lostHits and lep.convVeto and lep.sip3d < goodEl_sip3d: passConv = True elif eleID == 'CB': passConv = True # cuts already included in POG_Cuts_ID_SPRING15_25ns_v1_ConvVetoDxyDz_X passPostICHEPHLTHOverE = True # comment out again if (lep.hOverE < 0.04 and abs(lep.eta)>1.479) or abs(lep.eta)<=1.479 else False # fill if passIso and passConv and passPostICHEPHLTHOverE: selectedTightLeps.append(lep) selectedTightLepsIdx.append(idx) else: selectedVetoLeps.append(lep) # anti-selected elif not passMediumID: #passVetoID: # all anti leptons are veto for selected selectedVetoLeps.append(lep) # Iso check passIso = lep.miniPFRelIso_all < Lep_miniIsoCut # should be true anyway # other checks passOther = False if hasattr(lep, "hoe"): passOther = lep.hoe > 0.01 # fill if passIso and passOther: antiTightLeps.append(lep) antiTightLepsIdx.append(idx) else: antiVetoLeps.append(lep) # Veto leptons elif passVetoID: # the rest is veto for selected and anti selectedVetoLeps.append(lep) antiVetoLeps.append(lep) # end lepton loop ################### # EXTRA Loop for lepOther -- for anti-selected leptons ################### otherleps = [l for l in LepOther] #otherleps = [] for idx, lep in enumerate(otherleps): # check acceptance lepEta = abs(lep.eta) if lepEta > 2.4: continue # Pt cut if lep.pt < 10: continue # Iso cut -- to be compatible with the trigger if lep.miniPFRelIso_all > trig_miniIsoCut: continue ############ # Muons if (abs(lep.pdgId) == 13): ## Lower ID is POG_LOOSE (see cfg) # ID, IP and Iso check: #passID = lep.mediumMuonId == 1 passIso = lep.miniPFRelIso_all > muo_miniIsoCut # cuts like for the LepGood muons #passIP = abs(lep.dxy) < 0.05 and abs(lep.dz) < 0.1 #if passIso and passID and passIP: if passIso: antiTightLeps.append(lep) antiTightLepsIdx.append(idx) else: antiVetoLeps.append(lep) ############ # Electrons elif (abs(lep.pdgId) == 11): if (lepEta > eleEta): continue ## Iso selection: ele should have MiniIso < 0.4 (for trigger) if lep.miniPFRelIso_all > Lep_miniIsoCut: continue ## Set Ele IDs if eleID == 'CB': # ELE CutBased ID eidCB = lep.cutBased passMediumID = (eidCB >= 3 and lep.convVeto) passVetoID = (eidCB >= 1 and lep.convVeto) else: passMediumID = False passVetoID = False # Cuts for Anti-selected electrons if not passMediumID: # should always be true for LepOther # other checks passOther = False if hasattr(lep, "hoe"): passOther = lep.hoe > 0.01 #if not lep.conVeto: if passOther: antiTightLeps.append(lep) antiTightLepsIdx.append(idx) else: antiVetoLeps.append(lep) elif passVetoID: #all Medium+ eles in LepOther antiVetoLeps.append(lep) # choose common lepton collection: select selected or anti lepton if len(selectedTightLeps) > 0: tightLeps = selectedTightLeps tightLepsIdx = selectedTightLepsIdx vetoLeps = selectedVetoLeps ############# ############# # retrive and fill branches ############# # choose common lepton collection: select selected or anti lepton if len(selectedTightLeps) > 0: tightLeps = selectedTightLeps tightLepsIdx = selectedTightLepsIdx vetoLeps = selectedVetoLeps elif len(antiTightLeps) > 0: tightLeps = antiTightLeps tightLepsIdx = antiTightLepsIdx vetoLeps = antiVetoLeps else: tightLeps = [] tightLepsIdx = [] vetoLeps = [] nTightLeps = len(tightLeps) '''# Met metp4 = ROOT.TLorentzVector(0,0,0,0) if hasattr(event, 'metMuEGClean_pt'): metp4.SetPtEtaPhiM(event.metMuEGClean_pt,event.metMuEGClean_eta,event.metMuEGClean_phi,event.metMuEGClean_mass) else: metp4.SetPtEtaPhiM(met.pt,0,met.phi,0) if hasattr(event, 'metMuEGClean_pt'): pmiss =array.array('d',[event.metMuEGClean_pt * math.cos(event.metMuEGClean_phi), event.metMuEGClean_pt * math.sin(event.metMuEGClean_phi)] ) else: pmiss =array.array('d',[met.pt * math.cos(met.phi), met.pt * math.sin(met.phi)] )''' ##################################################################### ##################################################################### #################Jets, BJets, METS and filters ###################### ##################################################################### ##################################################################### ######## ### Jets ######## metp4 = ROOT.TLorentzVector(0, 0, 0, 0) Genmetp4 = ROOT.TLorentzVector(0, 0, 0, 0) if self.isMC: Genmetp4.SetPtEtaPhiM(genmet.pt, 0, genmet.phi, 0) Jets = Collection(event, "Jet") jets = [j for j in Jets if j.pt >= 20 and abs(j.eta) < 2.4] njet = len(jets) (met_px, met_py) = (met.pt * math.cos(met.phi), met.pt * math.sin(met.phi)) (met_px_nom, met_py_nom) = (met_px, met_py) # match reconstructed jets to generator level ones # (needed to evaluate JER scale factors and uncertainties) if self.isMC: rho = getattr(event, "fixedGridRhoFastjetAll") genJets = Collection(event, "GenJet") pairs = matchObjectCollection(Jets, genJets) for jet in jets: genJet = pairs[jet] if smearJER == True: (jet_pt_jerNomVal, jet_pt_jerUpVal, jet_pt_jerDownVal) = self.jetSmearer.getSmearValsPt( jet, genJet, rho) jet_pt_nom = jet_pt_jerNomVal * jet.pt if jet.pt > 15.: jet_cosPhi = math.cos(jet.phi) jet_sinPhi = math.sin(jet.phi) met_px_nom = met_px_nom - (jet_pt_nom - jet.pt) * jet_cosPhi met_py_nom = met_py_nom - (jet_pt_nom - jet.pt) * jet_sinPhi met_pt_nom = math.sqrt(met_px_nom**2 + met_py_nom**2) met_phi_nom = math.atan2(met_py_nom, met_px_nom) met.pt = met_pt_nom met.phi = met_phi_nom jet.pt = jet_pt_nom metp4.SetPtEtaPhiM( met.pt, 0., met.phi, 0.) # only use met vector to derive transverse quantities) centralJet30 = [] centralJet30idx = [] centralJet40 = [] cleanJets25 = [] cleanJets25idx = [] cleanJets = [] cleanJetsidx = [] # fill this flage but defults to 1 and then change it after the proper selection for i, j in enumerate(jets): if j.pt > 25: cleanJets25.append(j) cleanJets25idx.append(j) if j.pt > 30 and abs(j.eta) < centralEta: centralJet30.append(j) centralJet30idx.append(i) if j.pt > 40 and abs(j.eta) < centralEta: centralJet40.append(j) # jets 30 (cmg cleaning only) nCentralJet30 = len(centralJet30) btagWP = btag_MediumWP BJetMedium30 = [] BJetMedium30idx = [] BJetMedium40 = [] nBJetDeep = 0 cJet30Clean = [] dRminCut = 0.4 # Do cleaning a la CMG: clean max 1 jet for each lepton (the nearest) cJet30Clean = centralJet30 cleanJets30 = centralJet30 for i, j in enumerate(cJet30Clean): if j.btagCSVV2 > btagWP: BJetMedium30.append(j) BJetMedium30idx.append(j) if (j.btagDeepB) > btag_DeepMediumWP: nBJetDeep += 1 for i, j in enumerate(centralJet40): if j.btagCSVV2 > btagWP: BJetMedium40.append(j) nBJetMedium30 = len(BJetMedium30) ################################################################## # The following variables need to be double-checked for validity # ################################################################## ## B tagging WPs for CSVv2 (CSV-IVF) ## L: 0.423, M: 0.814, T: 0.941 ## from: https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideBTagging#Preliminary_working_or_operating bTagWP = 0.814 # MediumWP for CSVv2 #bTagWP = 0.732 # MediumWP for CMVA # min deltaPhi between a b-jet and MET; needs to be double-checked minDPhiBMET = 100 idxMinDPhiBMET = -999 for i, jet in enumerate(centralJet30): if jet.btagCSVV2 > bTagWP: dPhiBMET = abs(jet.p4().DeltaPhi(metp4)) if dPhiBMET < minDPhiBMET: minDPhiBMET = dPhiBMET idxMinDPhiBMET = i self.out.fillBranch("idxMinDPhiBMET", idxMinDPhiBMET) self.out.fillBranch("minDPhiBMET", minDPhiBMET) # min deltaPhi between a jet (first three jets) and MET; needs to be double-checked minDPhiJMET = 100 for i, jet in enumerate(centralJet30[:3]): dPhiJMET = abs(jet.p4().DeltaPhi(metp4)) if dPhiJMET < minDPhiJMET: minDPhiJMET = dPhiJMET self.out.fillBranch("minDPhiJMET", minDPhiJMET) # transverse mass of (closest (to MET) BJet, MET), (closest (to MET) BJet, lepton), # mass of (closest (to MET) BJet, lepton); need to be double-checked mTBJetMET = -999 mTLepMET = -999 mLepBJet = -999 if (idxMinDPhiBMET >= 0): SumMetClosestBJet = jets[idxMinDPhiBMET].p4() + metp4 self.out.fillBranch("mTClBPlusMET", SumMetClosestBJet.Mt()) mTBJetMET = mt_2(centralJet30[idxMinDPhiBMET].p4(), metp4) if nTightLeps >= 1: mLepBJet = (centralJet30[idxMinDPhiBMET].p4() + tightLeps[0].p4()).M() mTLepMET = mt_2(tightLeps[0].p4(), metp4) else: self.out.fillBranch("mTClBPlusMET", -999) self.out.fillBranch("mTBJetMET", mTBJetMET) self.out.fillBranch("mTLepMET", mTLepMET) self.out.fillBranch("mLepBJet", mLepBJet) # projection of MET along (MET + lepton + (closest (to MET) BJet)) sum; needs to be double-checked... MetZ1 = -9999 MetZ2 = -9999 MTW = -9999 MW1 = -9999 MW2 = -9999 neutrino1 = ROOT.TLorentzVector(0, 0, 0, 0) neutrino2 = ROOT.TLorentzVector(0, 0, 0, 0) if (nTightLeps == 1): NeutrZList = GetZfromM(tightLeps[0].p4(), metp4, 81) MTW = NeutrZList[0] MetZ1 = NeutrZList[1] MetZ2 = NeutrZList[2] neutrino1.SetXYZM(metp4.Px(), metp4.Py(), MetZ1, 0) neutrino2.SetXYZM(metp4.Px(), metp4.Py(), MetZ2, 0) MW1 = (neutrino1 + tightLeps[0].p4()).M() MW2 = (neutrino2 + tightLeps[0].p4()).M() self.out.fillBranch("MTW", MTW) self.out.fillBranch("MW1", MW1) self.out.fillBranch("MW2", MW2) # some extra plots MTbnu = [] LepBMass = [] MTtop = [] Mtop = [] METovTop = [] METTopPhi = [] MtopDecor = [] TopEt = [] TopPt = [] if (nTightLeps == 1): for i, jet in enumerate( centralJet30): #testing all jets as b-jet in top-reco if hasattr(event, 'metMuEGClean_pt'): ThisMTnub = math.sqrt( 2 * event.metMuEGClean_pt * jet.pt * (1 - math.cos(metp4.DeltaPhi(jet.p4())))) else: ThisMTnub = math.sqrt( 2 * met.pt * jet.pt * (1 - math.cos(metp4.DeltaPhi(jet.p4())))) MTbnu.append(ThisMTnub) # lep + jet vector lepJp4 = tightLeps[0].p4() + jet.p4() ThislepBMass = lepJp4.M() LepBMass.append(ThislepBMass) # top vector: MET + lep + jet topP4 = metp4 + lepJp4 TopEt.append(topP4.Et()) TopPt.append(topP4.Pt()) ThisMTtop = math.sqrt(81. * 81. + ThislepBMass * ThislepBMass + ThisMTnub * ThisMTnub) MTtop.append(ThisMTtop) if hasattr(event, 'metMuEGClean_pt'): ThisMetovTop = event.metMuEGClean_pt / topP4.Pt() else: ThisMetovTop = met.pt / topP4.Pt() METovTop.append(ThisMetovTop) ThisMetTop = metp4.DeltaPhi(metp4 + lepJp4) METTopPhi.append(ThisMetTop) TopMass1 = (neutrino1 + lepJp4).M() TopMass2 = (neutrino2 + lepJp4).M() #take smaller mtop of the two nu pz-solutions if TopMass1 > TopMass2: Mtop.append(TopMass2) else: Mtop.append(TopMass1) ThisMtopDecor1 = math.sqrt(lepJp4.M() * lepJp4.M() + (neutrino1 + jet.p4()).M() * (neutrino1 + jet.p4()).M() + 81 * 81) ThisMtopDecor2 = math.sqrt(lepJp4.M() * lepJp4.M() + (neutrino2 + jet.p4()).M() * (neutrino2 + jet.p4()).M() + 81 * 81) if ThisMtopDecor1 > ThisMtopDecor2: MtopDecor.append(ThisMtopDecor2) else: MtopDecor.append(ThisMtopDecor1) # fill them self.out.fillBranch("MTbnu", MTbnu) self.out.fillBranch("LepBMass", LepBMass) self.out.fillBranch("MTtop", MTtop) self.out.fillBranch("Mtop", Mtop) self.out.fillBranch("METovTop", METovTop) self.out.fillBranch("METTopPhi", METTopPhi) self.out.fillBranch("MtopDecor", MtopDecor) self.out.fillBranch("TopPt", TopPt) self.out.fillBranch("TopEt", TopEt) # nearest b jet to lead lepton minDphiLepB = 100 minDphiLepBidx = -1 if nTightLeps == 1: for i, jet in enumerate(centralJet30): if jet.btagCSVV2 > bTagWP: dPhiLepB = abs(jet.p4().DeltaPhi(tightLeps[0].p4())) if dPhiLepB < minDphiLepB: minDphiLepB = dPhiLepB minDphiLepBidx = i self.out.fillBranch("minDphiLepB", minDphiLepB) self.out.fillBranch("minDphiLepBidx", minDphiLepBidx) # TopVarsJetIdx = [] TopVarsMTbnuMin = [] TopVarsLepBMassMin = [] TopVarsMTtopMin = [] TopVarsMtopMin = [] TopVarsMETovTopMin = [] TopVarsMtopDecorMin = [] TopVarsTopPtMin = [] TopVarsTopEtMin = [] iBTagDict = { i: jets[idx].btagCSVV2 for i, idx in enumerate(centralJet30idx) } sortIdsByBTag = sorted(iBTagDict.items(), key=operator.itemgetter(1), reverse=True) bTaggedJetsSorted = sortIdsByBTag[:nBJetMedium30] # print bTaggedJetsSorted bTaggedJetsPPSorted = sortIdsByBTag[:nBJetMedium30 + 1] # print bTaggedJetsPPSorted ThreeBestBTags = sortIdsByBTag[:3] # print ThreeBestBTags # print sortIdsByBTag if nTightLeps == 1 and nCentralJet30 > 0: #0: minimum of b-tagged jets TopVarsMTbnuMin.append( minValueForIdxList(MTbnu, [ids[0] for ids in bTaggedJetsSorted])) TopVarsLepBMassMin.append( minValueForIdxList(LepBMass, [ids[0] for ids in bTaggedJetsSorted])) TopVarsMTtopMin.append( minValueForIdxList(MTtop, [ids[0] for ids in bTaggedJetsSorted])) TopVarsMtopMin.append( minValueForIdxList(Mtop, [ids[0] for ids in bTaggedJetsSorted])) TopVarsMETovTopMin.append( minValueForIdxList(METovTop, [ids[0] for ids in bTaggedJetsSorted])) TopVarsMtopDecorMin.append( minValueForIdxList(MtopDecor, [ids[0] for ids in bTaggedJetsSorted])) TopVarsTopPtMin.append( minValueForIdxList(TopPt, [ids[0] for ids in bTaggedJetsSorted])) TopVarsTopEtMin.append( minValueForIdxList(TopEt, [ids[0] for ids in bTaggedJetsSorted])) #1: minimum of b-tagged jets (+ adding next-best b-disc. jet) TopVarsMTbnuMin.append( minValueForIdxList(MTbnu, [ids[0] for ids in bTaggedJetsPPSorted])) TopVarsLepBMassMin.append( minValueForIdxList(LepBMass, [ids[0] for ids in bTaggedJetsPPSorted])) TopVarsMTtopMin.append( minValueForIdxList(MTtop, [ids[0] for ids in bTaggedJetsPPSorted])) TopVarsMtopMin.append( minValueForIdxList(Mtop, [ids[0] for ids in bTaggedJetsPPSorted])) TopVarsMETovTopMin.append( minValueForIdxList(METovTop, [ids[0] for ids in bTaggedJetsPPSorted])) TopVarsMtopDecorMin.append( minValueForIdxList(MtopDecor, [ids[0] for ids in bTaggedJetsPPSorted])) TopVarsTopPtMin.append( minValueForIdxList(TopPt, [ids[0] for ids in bTaggedJetsPPSorted])) TopVarsTopEtMin.append( minValueForIdxList(TopEt, [ids[0] for ids in bTaggedJetsPPSorted])) #2: always consider the three jets with the best b-tag values (no pass of any working-point required) TopVarsMTbnuMin.append( minValueForIdxList(MTbnu, [ids[0] for ids in ThreeBestBTags])) TopVarsLepBMassMin.append( minValueForIdxList(LepBMass, [ids[0] for ids in ThreeBestBTags])) TopVarsMTtopMin.append( minValueForIdxList(MTtop, [ids[0] for ids in ThreeBestBTags])) TopVarsMtopMin.append( minValueForIdxList(Mtop, [ids[0] for ids in ThreeBestBTags])) TopVarsMETovTopMin.append( minValueForIdxList(METovTop, [ids[0] for ids in ThreeBestBTags])) TopVarsMtopDecorMin.append( minValueForIdxList(MtopDecor, [ids[0] for ids in ThreeBestBTags])) TopVarsTopPtMin.append( minValueForIdxList(TopPt, [ids[0] for ids in ThreeBestBTags])) TopVarsTopEtMin.append( minValueForIdxList(TopEt, [ids[0] for ids in ThreeBestBTags])) if hasattr(tightLeps[0], 'genPartIdx'): mcMatchIdLep = tightLeps[0].genPartIdx iCorrectJet = -999 correctJetBTagged = False if abs(mcMatchIdLep) == 6: for i, jet in enumerate(centralJet30): if abs(jet.partonFlavour ) == 5 and jet.genJetIdx == mcMatchIdLep: iCorrectJet = i if jet.btagCSVV2 > bTagWP: correctJetBTagged = True #3: value for the correct b-jet (i.e. the one matching the lepton) TopVarsMTbnuMin.append( MTbnu[iCorrectJet] if iCorrectJet > -999 else -999) TopVarsLepBMassMin.append( LepBMass[iCorrectJet] if iCorrectJet > -999 else -999) TopVarsMTtopMin.append( MTtop[iCorrectJet] if iCorrectJet > -999 else -999) TopVarsMtopMin.append( Mtop[iCorrectJet] if iCorrectJet > -999 else -999) TopVarsMETovTopMin.append( METovTop[iCorrectJet] if iCorrectJet > -999 else -999) TopVarsMtopDecorMin.append( MtopDecor[iCorrectJet] if iCorrectJet > -999 else -999) TopVarsTopPtMin.append( TopPt[iCorrectJet] if iCorrectJet > -999 else -999) TopVarsTopEtMin.append( TopEt[iCorrectJet] if iCorrectJet > -999 else -999) foundCorrectBJetAndIsTagged = iCorrectJet > -999 and correctJetBTagged #4: value for the correct b-jet (if actually identified as b-jet (tagged)) TopVarsMTbnuMin.append(MTbnu[iCorrectJet] if foundCorrectBJetAndIsTagged else -999) TopVarsLepBMassMin.append( LepBMass[iCorrectJet] if foundCorrectBJetAndIsTagged else -999) TopVarsMTtopMin.append(MTtop[iCorrectJet] if foundCorrectBJetAndIsTagged else -999) TopVarsMtopMin.append( Mtop[iCorrectJet] if foundCorrectBJetAndIsTagged else -999) TopVarsMETovTopMin.append( METovTop[iCorrectJet] if foundCorrectBJetAndIsTagged else -999) TopVarsMtopDecorMin.append( MtopDecor[iCorrectJet] if foundCorrectBJetAndIsTagged else -999) TopVarsTopPtMin.append(TopPt[iCorrectJet] if foundCorrectBJetAndIsTagged else -999) TopVarsTopEtMin.append(TopEt[iCorrectJet] if foundCorrectBJetAndIsTagged else -999) #5: consider the jet closest in dphi to MET TopVarsMTbnuMin.append( MTbnu[idxMinDPhiBMET] if idxMinDPhiBMET != -999 else -999) TopVarsLepBMassMin.append(LepBMass[idxMinDPhiBMET] if idxMinDPhiBMET != -999 else -999) TopVarsMTtopMin.append( MTtop[idxMinDPhiBMET] if idxMinDPhiBMET != -999 else -999) TopVarsMtopMin.append( Mtop[idxMinDPhiBMET] if idxMinDPhiBMET != -999 else -999) TopVarsMETovTopMin.append(METovTop[idxMinDPhiBMET] if idxMinDPhiBMET != -999 else -999) TopVarsMtopDecorMin.append(MtopDecor[idxMinDPhiBMET] if idxMinDPhiBMET != -999 else -999) TopVarsTopPtMin.append( TopPt[idxMinDPhiBMET] if idxMinDPhiBMET != -999 else -999) TopVarsTopEtMin.append( TopEt[idxMinDPhiBMET] if idxMinDPhiBMET != -999 else -999) #6: nearest to lepton b jet TopVarsMTbnuMin.append( MTbnu[minDphiLepBidx] if minDphiLepBidx > -1 else -999) TopVarsLepBMassMin.append( LepBMass[minDphiLepBidx] if minDphiLepBidx > -1 else -999) TopVarsMTtopMin.append( MTtop[minDphiLepBidx] if minDphiLepBidx > -1 else -999) TopVarsMtopMin.append( Mtop[minDphiLepBidx] if minDphiLepBidx > -1 else -999) TopVarsMETovTopMin.append( METovTop[minDphiLepBidx] if minDphiLepBidx > -1 else -999) TopVarsMtopDecorMin.append( MtopDecor[minDphiLepBidx] if minDphiLepBidx > -1 else -999) TopVarsTopPtMin.append( TopPt[minDphiLepBidx] if minDphiLepBidx > -1 else -999) TopVarsTopEtMin.append( TopEt[minDphiLepBidx] if minDphiLepBidx > -1 else -999) else: for i in range(7): TopVarsMTbnuMin.append(-999) TopVarsLepBMassMin.append(-999) TopVarsMTtopMin.append(-999) TopVarsMtopMin.append(-999) TopVarsMETovTopMin.append(-999) TopVarsMtopDecorMin.append(-999) TopVarsTopPtMin.append(-999) TopVarsTopEtMin.append(-999) self.out.fillBranch("nBMinVariantsTopVars", 7) self.out.fillBranch("TopVarsMTbnuMin", TopVarsMTbnuMin) self.out.fillBranch("TopVarsLepBMassMin", TopVarsLepBMassMin) self.out.fillBranch("TopVarsMTtopMin", TopVarsMTtopMin) self.out.fillBranch("TopVarsMtopMin", TopVarsMtopMin) self.out.fillBranch("TopVarsMETovTopMin", TopVarsMETovTopMin) self.out.fillBranch("TopVarsMtopDecorMin", TopVarsMtopDecorMin) self.out.fillBranch("TopVarsTopPtMin", TopVarsTopPtMin) self.out.fillBranch("TopVarsTopEtMin", TopVarsTopEtMin) return True