def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("CommonClassifierAnalyzer started") selectedLeptonP4 = CvectorTLorentzVector() selectedLeptonCharge = Cvectordouble() selectedJetsP4 = CvectorTLorentzVector() selectedJetsCSV = Cvectordouble() looseJetsP4 = CvectorTLorentzVector() looseJetsCSV = Cvectordouble() for lep in event.good_leptons: selectedLeptonP4.push_back(lvec(lep)) selectedLeptonCharge.push_back(lep.charge) for jet in event.good_jets: selectedJetsP4.push_back(lvec(jet)) selectedJetsCSV.push_back(jet.btagCSV) looseJetsP4.push_back(lvec(jet)) looseJetsCSV.push_back(jet.btagCSV) for jet in event.loose_jets: looseJetsP4.push_back(lvec(jet)) looseJetsCSV.push_back(jet.btagCSV) metP4s = CvectorTLorentzVector() met_p4 = ROOT.TLorentzVector() met_p4.SetPtEtaPhiM(event.MET.pt, 0, event.MET.phi, 0) metP4s.push_back(met_p4) event.common_mem = [ROOT.MEMResult()] event.common_bdt = -2.0 event.common_bdt_withmem1 = -2.0 event.common_bdt_withmem2 = -2.0 if event.category_string.startswith("sl_"): event.common_bdt = self.bdtcalc_sl.GetBDTOutput(selectedLeptonP4, selectedJetsP4, selectedJetsCSV, looseJetsP4, looseJetsCSV, met_p4) if hasattr(event, "mem_results_tth"): mem_p_sig = event.mem_results_tth[self.conf.mem["methodOrder"].index("SL_0w2h2t")] mem_p_bkg = event.mem_results_ttbb[self.conf.mem["methodOrder"].index("SL_0w2h2t")] event.common_bdt_withmem1 = self.bdtcalc_sl_mem1.GetBDTOutput( selectedLeptonP4, selectedJetsP4, selectedJetsCSV, looseJetsP4, looseJetsCSV, met_p4, mem_p_sig.p/(mem_p_sig.p + 0.15 * mem_p_bkg.p) ) event.common_bdt_withmem2 = self.bdtcalc_sl_mem2.GetBDTOutput( selectedLeptonP4, selectedJetsP4, selectedJetsCSV, looseJetsP4, looseJetsCSV, met_p4, mem_p_sig.p, mem_p_bkg.p ) #FIXME #mem = self.memcalc.GetOutput(selectedLeptonP4, selectedLeptonCharge, selectedJetsP4, selectedJetsCSV, looseJetsP4, looseJetsCSV, met_p4) #event.common_mem = [mem] if event.category_string.startswith("dl_"): bdt = self.bdtcalc_dl.GetBDTOutput(selectedLeptonP4, selectedLeptonCharge, selectedJetsP4, selectedJetsCSV, met_p4) event.common_bdt = bdt if "debug" in self.conf.general["verbosity"]: print "bdt", event.category_string, event.common_bdt return event
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("WTagAnalyzer started") event.Wmass = 0.0 #we keep a set of the Q quark candidate jets event.wquark_candidate_jets = set([]) #Use untagged jets + any b-tagged jets that are not among the 4 highest by discriminator input_jets = event.buntagged_jets + event.selected_btagged_jets_low event.wquark_candidate_jet_pairs = [] #Need at least 2 untagged jets to calculate W mass if len(input_jets)>=2: bpair = self.find_best_pair(input_jets) #Get the best mass event.Wmass = bpair[0][0] #All masses event.Wmasses = [bpair[i][0] for i in range(len(bpair))] #Add at most 2 best pairs for i in range(min(len(bpair), 2)): event.wquark_candidate_jets.add(bpair[i][1]) #DS could the same jet end up here from i=0 and i=1? event.wquark_candidate_jets.add(bpair[i][2]) event.wquark_candidate_jet_pairs += [(bpair[i][1], bpair[i][2])] if "reco" in self.conf.general["verbosity"]: print("Wmass", event.Wmasses[i], #DS event.good_jets.index(bpair[i][1]), event.good_jets.index(bpair[i][2]) ) #If we can't calculate W mass, any untagged jets become the candidate else: for jet in input_jets: event.wquark_candidate_jets.add(jet) if "reco" in self.conf.general["verbosity"]: for pair in event.wquark_candidate_jet_pairs: print "wqpair", pair[0].pt, pair[1].pt event.passes_wtag = True return event
def _process(self, event): event.passes_multiclass = True setattr(event, 'PassedMulticlassAnalyzer', True) if "debug" in self.conf.general["verbosity"]: autolog("MulticlassAnalyzer started") if "multiclass" in self.conf.general["verbosity"]: print 'Printing from MulticlassAnalyzer! iEv = {0}'.format( event.iEv) if event.is_sl and event.numJets >= 6 and event.nBCSVM >= 2: # Calculate the input variables for the MVA var_dic = maketuple.calc_vars(event, "event") input_var_names = [ "j0_eta", "j0_mass", "j0_btagCSV", "j1_eta", "j1_mass", "j1_btagCSV", "j2_eta", "j2_mass", "j2_btagCSV", "j3_eta", "j3_mass", "j3_btagCSV", "j4_pt", "j4_eta", "j4_mass", "j4_btagCSV", "j5_pt", "j5_eta", "j5_mass", "j5_btagCSV" ] input_list = [var_dic[v] for v in input_var_names] input_arr = np.array(input_list) input_arr = input_arr.reshape(1, -1) # Run the MVA pred_class = self.model.predict(input_arr)[0] pred_probas = self.model.predict_proba(input_arr) # And store in event event.multiclass_class = pred_class event.multiclass_proba_ttb = pred_probas[0][0] event.multiclass_proba_tt2b = pred_probas[0][1] event.multiclass_proba_ttbb = pred_probas[0][2] event.multiclass_proba_ttcc = pred_probas[0][3] event.multiclass_proba_ttll = pred_probas[0][4] if "multiclass" in self.conf.general["verbosity"]: print '[MulticlassAnalyzer] Exiting MulticlassAnalyzer! event.PassedMulticlassAnalyzer = {0}'.format( event.PassedMulticlassAnalyzer) return event
def _process(self, event): event.passes_multiclass = True setattr( event, 'PassedMulticlassAnalyzer', True ) if "debug" in self.conf.general["verbosity"]: autolog("MulticlassAnalyzer started") if "multiclass" in self.conf.general["verbosity"]: print 'Printing from MulticlassAnalyzer! iEv = {0}'.format(event.iEv) if event.is_sl and event.numJets >= 6 and event.nBCSVM >= 2: # Calculate the input variables for the MVA var_dic = maketuple.calc_vars(event, "event") input_var_names = ["j0_eta", "j0_mass", "j0_btagCSV", "j1_eta", "j1_mass", "j1_btagCSV", "j2_eta", "j2_mass", "j2_btagCSV", "j3_eta", "j3_mass", "j3_btagCSV", "j4_pt", "j4_eta", "j4_mass", "j4_btagCSV", "j5_pt", "j5_eta", "j5_mass", "j5_btagCSV"] input_list = [var_dic[v] for v in input_var_names] input_arr = np.array(input_list) input_arr = input_arr.reshape(1,-1) # Run the MVA pred_class = self.model.predict(input_arr)[0] pred_probas = self.model.predict_proba(input_arr) # And store in event event.multiclass_class = pred_class event.multiclass_proba_ttb = pred_probas[0][0] event.multiclass_proba_tt2b = pred_probas[0][1] event.multiclass_proba_ttbb = pred_probas[0][2] event.multiclass_proba_ttcc = pred_probas[0][3] event.multiclass_proba_ttll = pred_probas[0][4] if "multiclass" in self.conf.general["verbosity"]: print '[MulticlassAnalyzer] Exiting MulticlassAnalyzer! event.PassedMulticlassAnalyzer = {0}'.format( event.PassedMulticlassAnalyzer ) return event
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("GenTTHAnalyzer started") event.nMatchSimB = 0 event.nMatchSimC = 0 lv_bs = map(lvec, event.GenBQuarkFromTop) for jet in event.good_jets: lv_j = lvec(jet) if (lv_j.Pt() > 20 and abs(lv_j.Eta()) < 2.5): if any([lv_b.DeltaR(lv_j) < 0.5 for lv_b in lv_bs]): continue absid = abs(jet.mcFlavour) if absid == 5: event.nMatchSimB += 1 if absid == 4: event.nMatchSimC += 1 return event
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("GenTTHAnalyzer started") #Get light quarks from W/Z event.l_quarks_w = event.GenWZQuark #Get b quarks from top event.b_quarks_t = event.GenBQuarkFromTop #Get b-quarks from H event.b_quarks_h = event.GenBQuarkFromH #Get leptonic top children #note that the tau lepton might be missing event.lep_top = event.GenLepFromTop event.nu_top = event.GenNuFromTop #cat_gen - a string specifying the ttbar decay mode event.cat_gen = None #cat_gen_n - a numerical value corresponding to the string event.cat_gen_n = -1 #all leptonic and hadronic gen tops event.genTopLep = [] event.genTopHad = [] #Only run top algos if len(event.GenTop) == 2: #Gen tops might be in random order gt1 = event.GenTop[0] gt2 = event.GenTop[1] dm1 = getattr(gt1, "decayMode", -1) dm2 = getattr(gt2, "decayMode", -1) #single-leptonic if ((dm1 == 0 and dm2==1) or (dm2==0 and dm1==1)): #First top is leptonic if dm1 == 0: event.genTopLep = [gt1] event.genTopHad = [gt2] #Second top is leptonic else: event.genTopLep = [gt2] event.genTopHad = [gt1] event.cat_gen = "sl" event.cat_gen_n = 0 elif (dm1 == 0 and dm2 == 0): event.cat_gen = "dl" event.cat_gen_n = 1 event.genTopLep = [gt1, gt2] event.genTopHad = [] elif (dm1 == 1 and dm2 == 1): event.cat_gen = "fh" event.cat_gen_n = 2 event.genTopHad = [gt1, gt2] event.genTopLep = [] else: event.genTopLep = [] event.genTopHad = [] #these are the quarks that would pass selection event.l_quarks_gen = [] event.b_quarks_gen_t = [] event.b_quarks_gen_h = [] nq = 0 #Find the light quarks from W that would pass jet selection #associate them with a transfer function for q in event.l_quarks_w: nq += 1 if self.pass_jet_selection(q): q.btagFlag = 0.0 q.tth_match_label = "wq" q.tth_match_index = nq attach_jet_transfer_function(q, self.conf) event.l_quarks_gen += [q] #Find the b quarks from top that would pass jet selection #associate them with a transfer function for q in event.b_quarks_t: nq += 1 if self.pass_jet_selection(q): q.btagFlag = 1.0 q.tth_match_label = "tb" q.tth_match_index = nq attach_jet_transfer_function(q, self.conf) event.b_quarks_gen_t += [q] #Find the b quarks from Higgs that would pass jet selection #associate them with a transfer function for q in event.b_quarks_h: nq += 1 if self.pass_jet_selection(q): q.btagFlag = 1.0 q.tth_match_label = "hb" q.tth_match_index = nq attach_jet_transfer_function(q, self.conf) event.b_quarks_gen_h += [q] #Number of reco jets matched to quarks from W, top, higgs event.nSelected_wq = len(event.l_quarks_gen) event.nSelected_tb = len(event.b_quarks_gen_t) event.nSelected_hb = len(event.b_quarks_gen_h) #Get the total MET from the neutrinos spx = 0 spy = 0 for nu in event.nu_top: p4 = lvec(nu) spx += p4.Px() spy += p4.Py() event.MET_tt = MET(px=spx, py=spy) #Get the total ttH visible pt at gen level spx = 0 spy = 0 for p in (event.l_quarks_w + event.b_quarks_t + event.b_quarks_h + event.lep_top): p4 = lvec(p) spx += p4.Px() spy += p4.Py() event.tth_px_gen = spx event.tth_py_gen = spy #Calculate tth recoil #rho = -met - tth_matched event.tth_rho_px_gen = -event.MET_gen.px - event.tth_px_gen event.tth_rho_py_gen = -event.MET_gen.py - event.tth_py_gen if "gen" in self.conf.general["verbosity"]: for j in event.l_quarks_w: autolog("gen q(W)", j.pt, j.eta, j.phi, j.mass, j.pdgId) for j in event.b_quarks_t: autolog("gen b(t)", j.pt, j.eta, j.phi, j.mass, j.pdgId) for j in event.lep_top: autolog("gen l(t)", j.pt, j.eta, j.phi, j.mass, j.pdgId) for j in event.nu_top: autolog("gen n(t)", j.pt, j.eta, j.phi, j.mass, j.pdgId) for j in event.b_quarks_h: autolog("gen b(h)", j.pt, j.eta, j.phi, j.mass, j.pdgId) autolog("gen cat", event.cat_gen, event.cat_gen_n) # In semi-leptonic events we need to figure out which top b is from if event.cat_gen == "sl": # If b pdgId has same sign as hadronic top pdgId, it's the one if event.b_quarks_t[0].pdgId * event.genTopHad[0].pdgId > 0: event.b_quarks_t[0].from_had_t = 1 event.b_quarks_t[1].from_had_t = 0 else: event.b_quarks_t[0].from_had_t = 0 event.b_quarks_t[1].from_had_t = 1 # In Di leptonic events no b quarks come from hadronic top elif event.cat_gen == "dl": for b in event.b_quarks_t: b.from_had_t = 0 # In All hadronic events both b quarks come from hadronic top elif event.cat_gen == "fh": for b in event.b_quarks_t: b.from_had_t = 1 else: for b in event.b_quarks_t: b.from_had_t = -1 #Store for each jet, specified by it's index in the jet #vector, if it is matched to any gen-level quarks matched_pairs = {} def match_jets_to_quarks(jetcoll, quarkcoll, label, label_numeric): for ij, j in enumerate(jetcoll): for iq, q in enumerate(quarkcoll): # Set to 1 for bs from hadronic top # Set to 0 for bs from hadronic top # Set to -1 for other stuff if label == "tb": if q.from_had_t == 1: numeric_b_from_had_t = 1 elif q.from_had_t == 0: numeric_b_from_had_t = 0 else: numeric_b_from_had_t = -1 else: numeric_b_from_had_t = -1 #find DeltaR between jet and quark l1 = lvec(q) l2 = lvec(j) dr = l1.DeltaR(l2) if dr < 0.3: #Jet already had a match: take the one with smaller dR if matched_pairs.has_key(ij): if matched_pairs[ij][1] > dr: matched_pairs[ij] = (label, iq, dr, label_numeric, numeric_b_from_had_t) else: matched_pairs[ij] = (label, iq, dr, label_numeric, numeric_b_from_had_t) #Find the best possible match for each individual jet match_jets_to_quarks(event.good_jets, event.l_quarks_gen, "wq", 0) match_jets_to_quarks(event.good_jets, event.b_quarks_gen_t, "tb", 1) match_jets_to_quarks(event.good_jets, event.b_quarks_gen_h, "hb", 2) #Number of reco jets matched to quarks from W, top, higgs event.nMatch_wq = 0 event.nMatch_tb = 0 event.nMatch_hb = 0 #As above, but also required to be tagged/untagged for b/light respectively. event.nMatch_wq_btag = 0 event.nMatch_tb_btag = 0 event.nMatch_hb_btag = 0 #Now check what each jet was matched to for ij, jet in enumerate(event.good_jets): jet.tth_match_label = None jet.tth_match_index = -1 jet.tth_match_dr = -1 jet.tth_match_label_numeric = -1 #Jet did not have a match (no jet index in matched_pairs) if not matched_pairs.has_key(ij): continue #continue jet loop #mlabel - string label of quark collection, e.g. "wq" #midx - index of quark in vector that the jet was matched to #mdr - delta R between jet and matched quark #mlabel_num - numeric label of quark collection, e.g. 0 #mlabel_num_bfromhadt - numeric label if the b is from hadronic top # -1 if not b or not from top # 0 if from leptonic top # 1 if from hadronic top mlabel, midx, mdr, mlabel_num, mlabel_num_bfromhadt = matched_pairs[ij] jet.tth_match_label = mlabel jet.tth_match_index = midx jet.tth_match_dr = mdr jet.tth_match_label_numeric = mlabel_num jet.tth_match_label_bfromhadt = mlabel_num_bfromhadt if mlabel == "wq": event.nMatch_wq += 1 #If this jet is considered to be un-tagged if jet.btagFlag == 0.0: event.nMatch_wq_btag += 1 elif mlabel == "tb": event.nMatch_tb += 1 #If this jet is considered to be b-tagged if jet.btagFlag == 1.0: event.nMatch_tb_btag += 1 elif mlabel == "hb": event.nMatch_hb += 1 if jet.btagFlag == 1.0: event.nMatch_hb_btag += 1 if "debug" in self.conf.general["verbosity"]: autolog("nSel {0}_{1}_{2} nMatch {3}_{4}_{5} nMatch_btag {6}_{7}_{8}".format( event.nSelected_wq, event.nSelected_tb, event.nSelected_hb, event.nMatch_wq, event.nMatch_tb, event.nMatch_hb, event.nMatch_wq_btag, event.nMatch_tb_btag, event.nMatch_hb_btag, )) if "matching" in self.conf.general["verbosity"]: matches = {"wq":event.l_quarks_w, "tb": event.b_quarks_t, "hb":event.b_quarks_h} for ij, jet in enumerate(event.good_jets): if not matched_pairs.has_key(ij): continue mlabel, midx, mdr, mlabel_num = matched_pairs[ij] autolog("jet match", ij, mlabel, midx, mdr, jet.pt, matches[mlabel][midx].pt) #reco-level tth-matched system spx = 0.0 spy = 0.0 for jet in event.good_jets: if not (jet.tth_match_label is None): p4 = lvec(jet) spx += p4.Px() spy += p4.Py() for lep in event.good_leptons: p4 = lvec(lep) match = False for glep in event.lep_top: p4g = lvec(glep) if p4g.DeltaR(p4) < 0.3: match = True break if match: spx += p4.Px() spy += p4.Py() event.tth_px_reco = spx event.tth_py_reco = spy #Calculate tth recoil #rho = -met - tth_matched event.tth_rho_px_reco = -event.MET.px - event.tth_px_reco event.tth_rho_py_reco = -event.MET.py - event.tth_py_reco #print out gen-level quarks if "input" in self.conf.general["verbosity"]: print "gen Q" for q in event.l_quarks_gen: print q.pt, q.eta, q.phi, q.mass, q.pdgId print "gen B" for q in event.b_quarks_gen: print q.pt, q.eta, q.phi, q.mass, q.pdgId return event
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("QGLRAnalyzer started") event.passes_qgl = True if not self.conf.general["doQGL"]: return event jets_for_qg_lr = event.buntagged_jets_bdisc[0:6] jet_probs = { kind: [ self.evaluate_jet_prob(j.pt, j.eta, j.qgl, kind) for j in jets_for_qg_lr ] for kind in ["flavour"] } best_4q_perm = 0 best_0q_perm = 0 best_flavour_4q_perm = 0 best_flavour_3q_perm = 0 best_flavour_2q_perm = 0 best_flavour_1q_perm = 0 best_flavour_0q_perm = 0 nqs4 = 4 if (len(jets_for_qg_lr) < 4): nqs4 = len(jets_for_qg_lr) nqs3 = 3 if (len(jets_for_qg_lr) < 3): nqs3 = len(jets_for_qg_lr) nqs2 = 2 if (len(jets_for_qg_lr) < 2): nqs2 = len(jets_for_qg_lr) nqs1 = 1 if (len(jets_for_qg_lr) < 1): nqs1 = len(jets_for_qg_lr) event.qg_lr_flavour_4q, best_flavour_4q_perm = self.qg_likelihood( jet_probs["flavour"], nqs4) event.qg_lr_flavour_3q, best_flavour_3q_perm = self.qg_likelihood( jet_probs["flavour"], nqs3) event.qg_lr_flavour_2q, best_flavour_2q_perm = self.qg_likelihood( jet_probs["flavour"], nqs2) event.qg_lr_flavour_1q, best_flavour_1q_perm = self.qg_likelihood( jet_probs["flavour"], nqs1) event.qg_lr_flavour_0q, best_flavour_0q_perm = self.qg_likelihood( jet_probs["flavour"], 0) def lratio(l1, l2): if l1 + l2 > 0: return l1 / (l1 + l2) else: return 0.0 def lratio2(l1, l2, l3): if l1 + l2 + l3 > 0: return l1 / (l1 + l2 + l3) else: return 0.0 def lratio3(l1, l2, l3, l4): if l1 + l2 + l3 + l4 > 0: return l1 / (l1 + l2 + l3 + l4) else: return 0.0 def lratio4(l1, l2, l3, l4, l5): if l1 + l2 + l3 + l4 + l5 > 0: return l1 / (l1 + l2 + l3 + l4 + l5) else: return 0.0 event.qg_LR_flavour_4q_0q = lratio(event.qg_lr_flavour_4q, event.qg_lr_flavour_0q) event.qg_LR_flavour_4q_1q = lratio(event.qg_lr_flavour_4q, event.qg_lr_flavour_1q) event.qg_LR_flavour_4q_2q = lratio(event.qg_lr_flavour_4q, event.qg_lr_flavour_2q) event.qg_LR_flavour_4q_3q = lratio(event.qg_lr_flavour_4q, event.qg_lr_flavour_3q) event.qg_LR_flavour_4q_0q_1q = lratio2(event.qg_lr_flavour_4q, event.qg_lr_flavour_0q, event.qg_lr_flavour_1q) event.qg_LR_flavour_4q_1q_2q = lratio2(event.qg_lr_flavour_4q, event.qg_lr_flavour_1q, event.qg_lr_flavour_2q) event.qg_LR_flavour_4q_2q_3q = lratio2(event.qg_lr_flavour_4q, event.qg_lr_flavour_2q, event.qg_lr_flavour_3q) event.qg_LR_flavour_4q_0q_1q_2q = lratio3(event.qg_lr_flavour_4q, event.qg_lr_flavour_0q, event.qg_lr_flavour_1q, event.qg_lr_flavour_2q) event.qg_LR_flavour_4q_1q_2q_3q = lratio3(event.qg_lr_flavour_4q, event.qg_lr_flavour_1q, event.qg_lr_flavour_2q, event.qg_lr_flavour_3q) event.qg_LR_flavour_4q_0q_1q_2q_3q = lratio4(event.qg_lr_flavour_4q, event.qg_lr_flavour_0q, event.qg_lr_flavour_1q, event.qg_lr_flavour_2q, event.qg_lr_flavour_3q) event.passes_qgl = True return event
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("MEMAnalyzer started") #Clean up any old MEM state self.vars_to_integrate.clear() self.vars_to_marginalize.clear() self.integrator.next_event() #Initialize members for tree filler event.mem_results_tth = [] event.mem_results_ttbb = [] res = {} if "meminput" in self.conf.general["verbosity"]: print "-----" print "MEM id={0},{1},{2} cat={3} cat_b={4} nj={5} nt={6} nel={7} nmu={8} syst={9}".format( event.input.run, event.input.lumi, event.input.evt, event.is_sl, event.is_dl, event.cat, event.cat_btag, event.numJets, event.nBCSVM, event.n_el_SL, event.n_mu_SL, getattr(event, "systematic", None), getattr(event, "systematic", None), ) for hypo in [MEM.Hypothesis.TTH, MEM.Hypothesis.TTBB]: skipped = [] for confname in self.memkeys: if self.mem_configs.has_key(confname): mem_cfg = self.mem_configs[confname] else: if confname in self.memkeysToRun: raise KeyError( "Asked for configuration={0} but this was never specified in mem_configs.keys={1}".format( confname, list(self.mem_configs.keys()) ) ) else: if "meminput" in self.conf.general["verbosity"]: print "skipping conf", confname fstate = MEM.FinalState.Undefined if "dl" in mem_cfg.mem_assumptions: fstate = MEM.FinalState.LL elif "sl" in mem_cfg.mem_assumptions: fstate = MEM.FinalState.LH elif "fh" in mem_cfg.mem_assumptions: fstate = MEM.FinalState.HH else: if confname in self.memkeysToRun: raise ValueError("Need to specify sl, dl of fh in assumptions but got {0}".format(str(mem_cfg.mem_assumptions))) else: res[(hypo, confname)] = MEM.MEMOutput() continue #if "meminput" in self.conf.general["verbosity"]: if ("meminput" in self.conf.general["verbosity"] or "debug" in self.conf.general["verbosity"]): autolog("MEMconf={0} fstate={1} MEMCand[l={2} b={3} q={4}] Reco[j={5} b={6} bLR={7}] MEMconf.doCalc={8} event.selection={9} toBeRun={10} isMC={11}".format( confname, fstate, len(mem_cfg.lepton_candidates(event)), len(mem_cfg.b_quark_candidates(event)), len(mem_cfg.l_quark_candidates(event)), event.numJets, event.nBCSVM, event.btag_LR_4b_2b, mem_cfg.do_calculate(event, mem_cfg), self.conf.mem["selection"](event), confname in self.memkeysToRun, self.cfg_comp.isMC )) #Run MEM if we did not explicitly disable it if (self.conf.mem["calcME"] and mem_cfg.do_calculate(event, mem_cfg) and self.conf.mem["selection"](event) and confname in self.memkeysToRun ): print "Integrator::run started hypo={0} conf={1} run:lumi:evt={2}:{3}:{4} {5} blr={6}".format( hypo, confname, event.input.run, event.input.lumi, event.input.evt, event.category_string, event.btag_LR_4b_2b ) self.configure_mem(event, mem_cfg) r = self.integrator.run( fstate, hypo, self.vars_to_integrate, self.vars_to_marginalize ) print "Integrator::run done hypo={0} conf={1} cat={2}".format(hypo, confname, event.cat) #DS res[(hypo, confname)] = r else: skipped += [confname] r = MEM.MEMOutput() res[(hypo, confname)] = r if "meminput" in self.conf.general["verbosity"]: print "skipped confs", skipped if "default" in self.memkeys: p1 = res[(MEM.Hypothesis.TTH, "default")].p p2 = res[(MEM.Hypothesis.TTBB, "default")].p event.mem_results_tth = [res[(MEM.Hypothesis.TTH, k)] for k in self.memkeys] event.mem_results_ttbb = [res[(MEM.Hypothesis.TTBB, k)] for k in self.memkeys] for confname in self.memkeysToRun: mem_cfg = self.mem_configs[confname] if "commoninput" in self.conf.general["verbosity"] and mem_cfg.do_calculate(event, mem_cfg): self.printInputs(event, confname) if "memoutput" in self.conf.general["verbosity"]: print [r.p for r in event.mem_results_tth] print [r.p for r in event.mem_results_ttbb]
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("QGLRAnalyzer started") event.passes_qgl = True if not self.conf.general["doQGL"]: return event jets_for_qg_lr = event.buntagged_jets_bdisc[0:6] jet_probs = { kind: [ self.evaluate_jet_prob(j.pt, j.eta, j.qgl, kind) for j in jets_for_qg_lr ] for kind in [ "flavour" ] } best_4q_perm = 0 best_0q_perm = 0 best_flavour_4q_perm = 0 best_flavour_3q_perm = 0 best_flavour_2q_perm = 0 best_flavour_1q_perm = 0 best_flavour_0q_perm = 0 nqs4 = 4 if (len(jets_for_qg_lr)<4): nqs4 = len(jets_for_qg_lr) nqs3 = 3 if (len(jets_for_qg_lr)<3): nqs3 = len(jets_for_qg_lr) nqs2 = 2 if (len(jets_for_qg_lr)<2): nqs2 = len(jets_for_qg_lr) nqs1 = 1 if (len(jets_for_qg_lr)<1): nqs1 = len(jets_for_qg_lr) event.qg_lr_flavour_4q, best_flavour_4q_perm = self.qg_likelihood(jet_probs["flavour"], nqs4) event.qg_lr_flavour_3q, best_flavour_3q_perm = self.qg_likelihood(jet_probs["flavour"], nqs3) event.qg_lr_flavour_2q, best_flavour_2q_perm = self.qg_likelihood(jet_probs["flavour"], nqs2) event.qg_lr_flavour_1q, best_flavour_1q_perm = self.qg_likelihood(jet_probs["flavour"], nqs1) event.qg_lr_flavour_0q, best_flavour_0q_perm = self.qg_likelihood(jet_probs["flavour"], 0) def lratio(l1, l2): if l1+l2>0: return l1/(l1+l2) else: return 0.0 def lratio2(l1, l2, l3): if l1+l2+l3>0: return l1/(l1+l2+l3) else: return 0.0 def lratio3(l1, l2, l3, l4): if l1+l2+l3+l4>0: return l1/(l1+l2+l3+l4) else: return 0.0 def lratio4(l1, l2, l3, l4, l5): if l1+l2+l3+l4+l5>0: return l1/(l1+l2+l3+l4+l5) else: return 0.0 event.qg_LR_flavour_4q_0q = lratio(event.qg_lr_flavour_4q, event.qg_lr_flavour_0q) event.qg_LR_flavour_4q_1q = lratio(event.qg_lr_flavour_4q, event.qg_lr_flavour_1q) event.qg_LR_flavour_4q_2q = lratio(event.qg_lr_flavour_4q, event.qg_lr_flavour_2q) event.qg_LR_flavour_4q_3q = lratio(event.qg_lr_flavour_4q, event.qg_lr_flavour_3q) event.qg_LR_flavour_4q_0q_1q = lratio2(event.qg_lr_flavour_4q, event.qg_lr_flavour_0q, event.qg_lr_flavour_1q) event.qg_LR_flavour_4q_1q_2q = lratio2(event.qg_lr_flavour_4q, event.qg_lr_flavour_1q, event.qg_lr_flavour_2q) event.qg_LR_flavour_4q_2q_3q = lratio2(event.qg_lr_flavour_4q, event.qg_lr_flavour_2q, event.qg_lr_flavour_3q) event.qg_LR_flavour_4q_0q_1q_2q = lratio3(event.qg_lr_flavour_4q, event.qg_lr_flavour_0q, event.qg_lr_flavour_1q, event.qg_lr_flavour_2q) event.qg_LR_flavour_4q_1q_2q_3q = lratio3(event.qg_lr_flavour_4q, event.qg_lr_flavour_1q, event.qg_lr_flavour_2q, event.qg_lr_flavour_3q) event.qg_LR_flavour_4q_0q_1q_2q_3q = lratio4(event.qg_lr_flavour_4q, event.qg_lr_flavour_0q, event.qg_lr_flavour_1q, event.qg_lr_flavour_2q, event.qg_lr_flavour_3q) event.passes_qgl = True return event
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("MEMAnalyzer started") #Clean up any old MEM state self.vars_to_integrate.clear() self.vars_to_marginalize.clear() self.integrator.next_event() #Initialize members for tree filler event.mem_results_tth = [] event.mem_results_ttbb = [] res = {} if "meminput" in self.conf.general["verbosity"]: print "-----" print "MEM id={0},{1},{2} cat={3} cat_b={4} nj={5} nt={6} nel={7} nmu={8} syst={9}".format( event.input.run, event.input.lumi, event.input.evt, event.is_sl, event.is_dl, event.cat, event.cat_btag, event.numJets, event.nBCSVM, event.n_el_SL, event.n_mu_SL, getattr(event, "systematic", None), getattr(event, "systematic", None), ) for hypo in [MEM.Hypothesis.TTH, MEM.Hypothesis.TTBB]: skipped = [] for confname in self.memkeysToRun: mem_cfg = self.conf.mem_configs[confname] fstate = MEM.FinalState.Undefined if "dl" in mem_cfg.mem_assumptions: fstate = MEM.FinalState.LL elif "sl" in mem_cfg.mem_assumptions: fstate = MEM.FinalState.LH elif "fh" in mem_cfg.mem_assumptions: fstate = MEM.FinalState.HH else: if confname in self.memkeysToRun: raise ValueError("Need to specify sl, dl of fh in assumptions but got {0}".format(str(mem_cfg.mem_assumptions))) else: res[(hypo, confname)] = MEM.MEMOutput() continue #if "meminput" in self.conf.general["verbosity"]: if ("meminput" in self.conf.general["verbosity"] or "debug" in self.conf.general["verbosity"]): autolog("MEMconf={0} fstate={1} MEMCand[l={2} b={3} q={4}] Reco[j={5} b={6} bLR={7}] MEMconf.doCalc={8} event.selection={9} toBeRun={10} isMC={11}".format( confname, fstate, len(mem_cfg.lepton_candidates(event)), len(mem_cfg.b_quark_candidates(event)), len(mem_cfg.l_quark_candidates(event)), event.numJets, event.nBCSVM, event.btag_LR_4b_2b, mem_cfg.do_calculate(event, mem_cfg), self.conf.mem["selection"](event), confname in self.memkeysToRun, self.cfg_comp.isMC )) #Run MEM if we did not explicitly disable it if (self.conf.mem["calcME"] and mem_cfg.do_calculate(event, mem_cfg) and self.conf.mem["selection"](event) and confname in self.memkeysToRun ): print "Integrator::run started hypo={0} conf={1} run:lumi:evt={2}:{3}:{4} {5} blr={6}".format( hypo, confname, event.input.run, event.input.lumi, event.input.evt, event.category_string, event.btag_LR_4b_2b ) print "Integrator conf: b={0} l={1}".format( len(mem_cfg.b_quark_candidates(event)), len(mem_cfg.l_quark_candidates(event)) ) self.configure_mem(event, mem_cfg) r = self.integrator.run( fstate, hypo, self.vars_to_integrate, self.vars_to_marginalize ) print "Integrator::run done hypo={0} conf={1} cat={2}".format(hypo, confname, event.cat) #DS res[(hypo, confname)] = r else: skipped += [confname] r = MEM.MEMOutput() res[(hypo, confname)] = r if "meminput" in self.conf.general["verbosity"]: print "skipped confs", skipped #Add MEM results to event for key in self.memkeysToRun: for (hypo_name, hypo) in [ ("tth", MEM.Hypothesis.TTH), ("ttbb", MEM.Hypothesis.TTBB) ]: mem_res = res[(hypo, key)] setattr(event, "mem_{0}_{1}".format(hypo_name, key), mem_res) #Create MEM permutations perms = [] for iperm in range(mem_res.num_perm): perm = mem_res.permutation_indexes[iperm] v_p = normalize_proba([v for v in mem_res.permutation_probas[iperm]]) v_p_tf = normalize_proba([v for v in mem_res.permutation_probas_transfer[iperm]]) v_p_me = normalize_proba([v for v in mem_res.permutation_probas_me[iperm]]) mem_perm = MEMPermutation( iperm, [_p for _p in perm], np.mean(v_p), np.std(v_p), np.mean(v_p_tf), np.std(v_p_tf), np.mean(v_p_me), np.std(v_p_me), ) perms += [mem_perm] setattr(event, "mem_{0}_{1}_perm".format(hypo_name, key), perms) #print out the JSON format for the standalone integrator for confname in self.memkeysToRun: mem_cfg = self.mem_configs[confname] if "commoninput" in self.conf.general["verbosity"] and mem_cfg.do_calculate(event, mem_cfg): self.printInputs(event, confname) event.passes_mem = True return event
def configure_mem(self, event, mem_cfg): self.integrator.set_cfg(mem_cfg.cfg) self.vars_to_integrate.clear() self.vars_to_marginalize.clear() self.integrator.next_event() set_integration_vars(self.vars_to_integrate, self.vars_to_marginalize, mem_cfg.mem_assumptions) bquarks = sorted(list(mem_cfg.b_quark_candidates(event)), key=lambda x: x.pt, reverse=True) if len(bquarks) > mem_cfg.maxBJets: autolog( "More than {0} b-quarks supplied, dropping last {1} from MEM". format(mem_cfg.maxBJets, len(bquarks) - mem_cfg.maxBJets)) for q in bquarks[mem_cfg.maxBJets:]: print "Dropping jet", q.pt, q.eta bquarks = bquarks[:mem_cfg.maxBJets] lquarks = sorted(list(mem_cfg.l_quark_candidates(event)), key=lambda x: x.pt, reverse=True) if len(lquarks) > mem_cfg.maxLJets: autolog( "More than {0} l-quarks supplied, dropping last {1} from MEM". format(mem_cfg.maxLJets, len(lquarks) - mem_cfg.maxLJets)) for q in lquarks[mem_cfg.maxLJets:]: print "Dropping jet", q.pt, q.eta lquarks = lquarks[:mem_cfg.maxLJets] ##Only take up to 4 candidates, otherwise runtimes become too great for jet in bquarks + lquarks: add_obj( self.integrator, MEM.ObjectType.Jet, p4s=(jet.pt, jet.eta, jet.phi, jet.mass), obs_dict={ MEM.Observable.BTAG: jet.btagFlag, #MEM.Observable.CSV: getattr(jet, mem_cfg.btagMethod, -1), #MEM.Observable.PDGID: getattr(jet, "PDGID", 0) }, tf_dict={ MEM.TFType.bReco: jet.tf_b, MEM.TFType.qReco: jet.tf_l, }) if "meminput" in self.conf.general["verbosity"]: print "memBQuark" if jet in bquarks else "memLQuark",\ jet.pt, jet.eta, jet.phi, jet.mass,\ ", Flag: ", jet.btagFlag,\ ", CSV: ", getattr(jet, mem_cfg.btagMethod, -1),\ ", PDGID: ", getattr(jet, "PDGID", -1),\ ", Match: ", jet.tth_match_label, jet.tth_match_index for lep in mem_cfg.lepton_candidates(event): add_obj( self.integrator, MEM.ObjectType.Lepton, p4s=(lep.pt, lep.eta, lep.phi, lep.mass), obs_dict={MEM.Observable.CHARGE: lep.charge}, ) if "meminput" in self.conf.general["verbosity"]: print "memLepton", lep.pt, lep.eta, lep.phi, lep.mass, lep.charge met_cand = mem_cfg.met_candidates(event) if "meminput" in self.conf.general["verbosity"]: print "memMET", met_cand.pt, met_cand.phi add_obj( self.integrator, MEM.ObjectType.MET, #MET is caused by massless object p4s=(met_cand.pt, 0, met_cand.phi, 0), )
def process(self, event): event.mu = filter( lambda x: abs(x.pdgId) == 13, event.selLeptons, ) if "debug" in self.conf.general["verbosity"]: autolog("input muons: ", len(event.mu)) for it in event.mu: (self.conf.leptons["mu"]["debug"])(it) event.el = filter( lambda x: abs(x.pdgId) == 11, event.selLeptons, ) if "debug" in self.conf.general["verbosity"]: autolog("input electrons: ", len(event.el)) for it in event.el: (self.conf.leptons["el"]["debug"])(it) for id_type in ["SL", "DL", "veto"]: sumleps = [] for lep_flavour in ["mu", "el"]: lepcuts = self.conf.leptons[lep_flavour][id_type] incoll = getattr(event, lep_flavour) isotype = self.conf.leptons[lep_flavour]["isotype"] isocut = lepcuts.get("iso", 99) if "debug" in self.conf.general["verbosity"]: autolog("input collection", id_type, lep_flavour) for lep in incoll: autolog(lep.pt, lep.eta, lep.pdgId) leps = filter( lambda x, lepcuts=lepcuts: ( x.pt > lepcuts.get( "pt", 0) #pt cut may be optional in case of DL and abs(x.eta) < lepcuts["eta"]), incoll) if "debug" in self.conf.general["verbosity"]: autolog("after eta") for lep in leps: autolog(lep.pt, lep.eta, lep.pdgId) #Apply isolation cut if isotype != "none": leps = filter(lambda x, isotype=isotype, isocut=isocut: abs(getattr(x, isotype)) < isocut, leps) if "debug" in self.conf.general["verbosity"]: autolog("after iso", isotype) for lep in leps: autolog(lep.pt, lep.eta, lep.pdgId) #Apply ID cut leps = filter(lepcuts["idcut"], leps) if "debug" in self.conf.general["verbosity"]: autolog("after id") for lep in leps: autolog(lep.pt, lep.eta, lep.pdgId) sumleps += leps lepname = lep_flavour + "_" + id_type setattr(event, lepname, leps) setattr(event, "n_" + lepname, len(leps)) #end of lep_flavour loop setattr(event, "lep_{0}".format(id_type), sumleps) setattr(event, "n_lep_{0}".format(id_type), len(sumleps)) #end of id_type loop event.lep_SL = sorted(event.lep_SL, key=lambda x: x.pt, reverse=True) event.lep_DL = sorted(event.lep_DL, key=lambda x: x.pt, reverse=True) event.lep_veto = sorted(event.lep_veto, key=lambda x: x.pt, reverse=True) #Apply two-stage pt cut on DL leptons lep_DL_afterpt = [] for lep in event.lep_DL: if len(lep_DL_afterpt) == 0: ptcut = self.conf.leptons["DL"]["pt_leading"] else: ptcut = self.conf.leptons["DL"]["pt_subleading"] if lep.pt > ptcut: lep_DL_afterpt += [lep] event.lep_DL = lep_DL_afterpt event.n_lep_DL = len(event.lep_DL) if "debug" in self.conf.general["verbosity"]: for lep in event.lep_SL + event.lep_DL + event.lep_veto: if lep in event.mu: f = self.conf.leptons["mu"]["debug"] elif lep in event.el: f = self.conf.leptons["el"]["debug"] else: f = lambda x: x prefix = "" if lep in event.lep_SL: prefix += "SL " if lep in event.lep_DL: prefix += "DL " if lep in event.lep_DL: prefix += "veto " autolog(prefix) f(lep) autolog("n_lep_tight={0}, n_lep_loose={1}, n_lep_tight_veto={2}". format(event.n_lep_SL, event.n_lep_DL, event.n_lep_veto)) event.is_sl = (event.n_lep_SL == 1 and event.n_lep_veto == 1) event.is_dl = (event.n_lep_DL == 2 and event.n_lep_veto == 2) event.is_fh = (not event.is_sl and not event.is_dl) if "debug" in self.conf.general["verbosity"]: autolog("is_sl, is_dl, is_fh", event.is_sl, event.is_dl, event.is_fh) #Calculate di-lepton system momentum event.dilepton_p4 = ROOT.TLorentzVector() if event.is_sl: event.good_leptons = event.lep_SL event.veto_leptons = event.lep_veto elif event.is_dl: event.good_leptons = event.lep_DL event.veto_leptons = event.lep_veto for lv in [lvec(l) for l in event.good_leptons]: event.dilepton_p4 += lv elif event.is_fh: event.good_leptons = [] event.veto_leptons = [] event.good_leptons = sorted(event.good_leptons, key=lambda x: x.pt, reverse=True) event.veto_leptons = sorted(event.veto_leptons, key=lambda x: x.pt, reverse=True) #Match good signal leptons to gen-leptons if self.cfg_comp.isMC: from PhysicsTools.HeppyCore.utils.deltar import matchObjectCollection #matchObjectCollection(event.good_leptons, event.GenLepFromTop, 0.3) #apply configuration-dependent selection passes = self.conf.leptons["selection"](event) if "debug" in self.conf.general["verbosity"]: autolog("LeptonAnalyzer selection", passes) if event.is_sl and event.is_dl: autolog("The event (%s,%s,%s) is both sl and dl" % (event.input.run, event.input.lumi, event.input.evt)) autolog("SL mu") for lep in event.mu_SL: (self.conf.leptons["mu"]["debug"])(lep) autolog("DL mu") for lep in event.mu_DL: (self.conf.leptons["mu"]["debug"])(lep) autolog("SL el") for lep in event.el_SL: (self.conf.leptons["el"]["debug"])(lep) autolog("DL el") for lep in event.el_DL: (self.conf.leptons["el"]["debug"])(lep) autolog("veto mu") for lep in event.mu_veto: (self.conf.leptons["mu"]["debug"])(lep) autolog("veto el") for lep in event.mu_veto: (self.conf.leptons["el"]["debug"])(lep) passes = False autolog("WARNING: Overlapping event") return self.conf.general["passall"] or passes
def process(self, event): event.mu = filter( lambda x: abs(x.pdgId) == 13, event.selLeptons, ) if "debug" in self.conf.general["verbosity"]: autolog("input muons: ", len(event.mu)) for it in event.mu: (self.conf.leptons["mu"]["debug"])(it) event.el = filter( lambda x: abs(x.pdgId) == 11, event.selLeptons, ) if "debug" in self.conf.general["verbosity"]: autolog("input electrons: ", len(event.el)) for it in event.el: (self.conf.leptons["el"]["debug"])(it) for id_type in ["SL", "DL", "veto"]: sumleps = [] for lep_flavour in ["mu", "el"]: lepcuts = self.conf.leptons[lep_flavour][id_type] incoll = getattr(event, lep_flavour) isotype = self.conf.leptons[lep_flavour]["isotype"] isocut = lepcuts.get("iso", 99) if "debug" in self.conf.general["verbosity"]: autolog("input collection", id_type, lep_flavour) for lep in incoll: autolog(lep.pt, lep.eta, lep.pdgId) leps = filter( lambda x, lepcuts=lepcuts: ( x.pt > lepcuts.get("pt", 0) #pt cut may be optional in case of DL and abs(x.eta) < lepcuts["eta"] ), incoll ) if "debug" in self.conf.general["verbosity"]: autolog("after eta") for lep in leps: autolog(lep.pt, lep.eta, lep.pdgId) #Apply isolation cut if isotype != "none": leps = filter( lambda x, isotype=isotype, isocut=isocut: abs(getattr(x, isotype)) < isocut, leps ) if "debug" in self.conf.general["verbosity"]: autolog("after iso", isotype) for lep in leps: autolog(lep.pt, lep.eta, lep.pdgId) #Apply ID cut leps = filter(lepcuts["idcut"], leps) if "debug" in self.conf.general["verbosity"]: autolog("after id") for lep in leps: autolog(lep.pt, lep.eta, lep.pdgId) sumleps += leps lepname = lep_flavour + "_" + id_type setattr(event, lepname, leps) setattr(event, "n_"+ lepname, len(leps)) #end of lep_flavour loop setattr(event, "lep_{0}".format(id_type), sumleps) setattr(event, "n_lep_{0}".format(id_type), len(sumleps)) #end of id_type loop event.lep_SL = sorted(event.lep_SL, key=lambda x: x.pt, reverse=True) event.lep_DL = sorted(event.lep_DL, key=lambda x: x.pt, reverse=True) event.lep_veto = sorted(event.lep_veto, key=lambda x: x.pt, reverse=True) #Apply two-stage pt cut on DL leptons lep_DL_afterpt = [] for lep in event.lep_DL: if len(lep_DL_afterpt) == 0: ptcut = self.conf.leptons["DL"]["pt_leading"] else: ptcut = self.conf.leptons["DL"]["pt_subleading"] if lep.pt > ptcut: lep_DL_afterpt += [lep] event.lep_DL = lep_DL_afterpt event.n_lep_DL = len(event.lep_DL) if "debug" in self.conf.general["verbosity"]: for lep in event.lep_SL + event.lep_DL + event.lep_veto: if lep in event.mu: f = self.conf.leptons["mu"]["debug"] elif lep in event.el: f = self.conf.leptons["el"]["debug"] else: f = lambda x: x prefix = "" if lep in event.lep_SL: prefix += "SL " if lep in event.lep_DL: prefix += "DL " if lep in event.lep_DL: prefix += "veto " autolog(prefix) f(lep) autolog("n_lep_tight={0}, n_lep_loose={1}, n_lep_tight_veto={2}".format( event.n_lep_SL, event.n_lep_DL, event.n_lep_veto) ) event.is_sl = (event.n_lep_SL == 1 and event.n_lep_veto == 1) event.is_dl = (event.n_lep_DL == 2 and event.n_lep_veto == 2) event.is_fh = (not event.is_sl and not event.is_dl) if "debug" in self.conf.general["verbosity"]: autolog("is_sl, is_dl, is_fh", event.is_sl, event.is_dl, event.is_fh) #Calculate di-lepton system momentum event.dilepton_p4 = ROOT.TLorentzVector() if event.is_sl: event.good_leptons = event.lep_SL event.veto_leptons = event.lep_veto elif event.is_dl: event.good_leptons =event.lep_DL event.veto_leptons = event.lep_veto for lv in [lvec(l) for l in event.good_leptons]: event.dilepton_p4 += lv elif event.is_fh: event.good_leptons = [] event.veto_leptons = [] event.good_leptons = sorted(event.good_leptons, key=lambda x: x.pt, reverse=True) event.veto_leptons = sorted(event.veto_leptons, key=lambda x: x.pt, reverse=True) #Match good signal leptons to gen-leptons if self.cfg_comp.isMC: from PhysicsTools.HeppyCore.utils.deltar import matchObjectCollection #matchObjectCollection(event.good_leptons, event.GenLepFromTop, 0.3) #apply configuration-dependent selection passes = self.conf.leptons["selection"](event) if "debug" in self.conf.general["verbosity"]: autolog("LeptonAnalyzer selection", passes) if event.is_sl and event.is_dl: autolog("The event (%s,%s,%s) is both sl and dl" % ( event.input.run,event.input.lumi,event.input.evt) ) autolog("SL mu") for lep in event.mu_SL: (self.conf.leptons["mu"]["debug"])(lep) autolog("DL mu") for lep in event.mu_DL: (self.conf.leptons["mu"]["debug"])(lep) autolog("SL el") for lep in event.el_SL: (self.conf.leptons["el"]["debug"])(lep) autolog("DL el") for lep in event.el_DL: (self.conf.leptons["el"]["debug"])(lep) autolog("veto mu") for lep in event.mu_veto: (self.conf.leptons["mu"]["debug"])(lep) autolog("veto el") for lep in event.mu_veto: (self.conf.leptons["el"]["debug"])(lep) passes = False autolog("WARNING: Overlapping event") return self.conf.general["passall"] or passes
def _process(self, event): if not self.cfg_comp.isMC: return event if "debug" in self.conf.general["verbosity"]: autolog("GenTTHAnalyzer started") #Get light quarks from W/Z event.l_quarks_w = event.GenWZQuark #Get b quarks from top event.b_quarks_t = event.GenBQuarkFromTop #Get b-quarks from H event.b_quarks_h = event.GenBQuarkFromH #Get leptonic top children #note that the tau lepton might be missing event.lep_top = event.GenLepFromTop event.nu_top = event.GenNuFromTop #cat_gen - a string specifying the ttbar decay mode event.cat_gen = None #cat_gen_n - a numerical value corresponding to the string event.cat_gen_n = -1 #all leptonic and hadronic gen tops event.genTopLep = [] event.genTopHad = [] #Only run top algos if len(event.GenTop) == 2: #Gen tops might be in random order gt1 = event.GenTop[0] gt2 = event.GenTop[1] dm1 = getattr(gt1, "decayMode", -1) dm2 = getattr(gt2, "decayMode", -1) #single-leptonic if ((dm1 == 0 and dm2 == 1) or (dm2 == 0 and dm1 == 1)): #First top is leptonic if dm1 == 0: event.genTopLep = [gt1] event.genTopHad = [gt2] #Second top is leptonic else: event.genTopLep = [gt2] event.genTopHad = [gt1] event.cat_gen = "sl" event.cat_gen_n = 0 elif (dm1 == 0 and dm2 == 0): event.cat_gen = "dl" event.cat_gen_n = 1 event.genTopLep = [gt1, gt2] event.genTopHad = [] elif (dm1 == 1 and dm2 == 1): event.cat_gen = "fh" event.cat_gen_n = 2 event.genTopHad = [gt1, gt2] event.genTopLep = [] else: event.genTopLep = [] event.genTopHad = [] #these are the quarks that would pass selection event.l_quarks_gen = [] event.b_quarks_gen_t = [] event.b_quarks_gen_h = [] nq = 0 #Find the light quarks from W that would pass jet selection #associate them with a transfer function for q in event.l_quarks_w: nq += 1 if self.pass_jet_selection(q): q.btagFlag = 0.0 q.tth_match_label = "wq" q.tth_match_index = nq attach_jet_transfer_function(q, self.conf) event.l_quarks_gen += [q] #Find the b quarks from top that would pass jet selection #associate them with a transfer function for q in event.b_quarks_t: nq += 1 if self.pass_jet_selection(q): q.btagFlag = 1.0 q.tth_match_label = "tb" q.tth_match_index = nq attach_jet_transfer_function(q, self.conf) event.b_quarks_gen_t += [q] #Find the b quarks from Higgs that would pass jet selection #associate them with a transfer function for q in event.b_quarks_h: nq += 1 if self.pass_jet_selection(q): q.btagFlag = 1.0 q.tth_match_label = "hb" q.tth_match_index = nq attach_jet_transfer_function(q, self.conf) event.b_quarks_gen_h += [q] #Number of reco jets matched to quarks from W, top, higgs event.nSelected_wq = len(event.l_quarks_gen) event.nSelected_tb = len(event.b_quarks_gen_t) event.nSelected_hb = len(event.b_quarks_gen_h) #Get the total MET from the neutrinos spx = 0 spy = 0 for nu in event.nu_top: p4 = lvec(nu) spx += p4.Px() spy += p4.Py() event.MET_tt = MET(px=spx, py=spy) #Get the total ttH visible pt at gen level spx = 0 spy = 0 for p in (event.l_quarks_w + event.b_quarks_t + event.b_quarks_h + event.lep_top): p4 = lvec(p) spx += p4.Px() spy += p4.Py() event.tth_px_gen = spx event.tth_py_gen = spy #Calculate tth recoil #rho = -met - tth_matched event.tth_rho_px_gen = -event.MET_gen.px - event.tth_px_gen event.tth_rho_py_gen = -event.MET_gen.py - event.tth_py_gen if "gen" in self.conf.general["verbosity"]: for j in event.l_quarks_w: autolog("gen q(W)", j.pt, j.eta, j.phi, j.mass, j.pdgId) for j in event.b_quarks_t: autolog("gen b(t)", j.pt, j.eta, j.phi, j.mass, j.pdgId) for j in event.lep_top: autolog("gen l(t)", j.pt, j.eta, j.phi, j.mass, j.pdgId) for j in event.nu_top: autolog("gen n(t)", j.pt, j.eta, j.phi, j.mass, j.pdgId) for j in event.b_quarks_h: autolog("gen b(h)", j.pt, j.eta, j.phi, j.mass, j.pdgId) autolog("gen cat", event.cat_gen, event.cat_gen_n) # In semi-leptonic events we need to figure out which top b is from if event.cat_gen == "sl": # If b pdgId has same sign as hadronic top pdgId, it's the one if event.b_quarks_t[0].pdgId * event.genTopHad[0].pdgId > 0: event.b_quarks_t[0].from_had_t = 1 event.b_quarks_t[1].from_had_t = 0 else: event.b_quarks_t[0].from_had_t = 0 event.b_quarks_t[1].from_had_t = 1 # In Di leptonic events no b quarks come from hadronic top elif event.cat_gen == "dl": for b in event.b_quarks_t: b.from_had_t = 0 # In All hadronic events both b quarks come from hadronic top elif event.cat_gen == "fh": for b in event.b_quarks_t: b.from_had_t = 1 else: for b in event.b_quarks_t: b.from_had_t = -1 #Store for each jet, specified by it's index in the jet #vector, if it is matched to any gen-level quarks matched_pairs = {} def match_jets_to_quarks(jetcoll, quarkcoll, label, label_numeric): for ij, j in enumerate(jetcoll): for iq, q in enumerate(quarkcoll): # Set to 1 for bs from hadronic top # Set to 0 for bs from hadronic top # Set to -1 for other stuff if label == "tb": if q.from_had_t == 1: numeric_b_from_had_t = 1 elif q.from_had_t == 0: numeric_b_from_had_t = 0 else: numeric_b_from_had_t = -1 else: numeric_b_from_had_t = -1 #find DeltaR between jet and quark l1 = lvec(q) l2 = lvec(j) dr = l1.DeltaR(l2) if dr < 0.3: #Jet already had a match: take the one with smaller dR if not matched_pairs.has_key(ij): matched_pairs[ij] = [] matched_pairs[ij] += [(label, iq, dr, label_numeric, numeric_b_from_had_t)] #Find the best possible match for each individual jet #light-quarks from W match_jets_to_quarks(event.good_jets, event.l_quarks_gen, "wq", 0) #b-quarks from top match_jets_to_quarks(event.good_jets, event.b_quarks_gen_t, "tb", 1) #b-quarks from Higgs match_jets_to_quarks(event.good_jets, event.b_quarks_gen_h, "hb", 2) #gluons from top match_jets_to_quarks(event.good_jets, event.GenGluonFromTop, "tg", 3) #gluons from b match_jets_to_quarks(event.good_jets, event.GenGluonFromB, "bg", 4) #Number of reco jets matched to quarks from W, top, higgs event.nMatch_wq = 0 event.nMatch_tb = 0 event.nMatch_hb = 0 #As above, but also required to be tagged/untagged for b/light respectively. event.nMatch_wq_btag = 0 event.nMatch_tb_btag = 0 event.nMatch_hb_btag = 0 #Now check what each jet was matched to for ij, jet in enumerate(event.good_jets): jet.tth_match_label = None jet.tth_match_index = -1 jet.tth_match_dr = -1 jet.tth_match_label_numeric = -1 #Jet did not have a match (no jet index in matched_pairs) if not matched_pairs.has_key(ij): continue #continue jet loop #mlabel - string label of quark collection, e.g. "wq" #midx - index of quark in vector that the jet was matched to #mdr - delta R between jet and matched quark #mlabel_num - numeric label of quark collection, e.g. 0 #mlabel_num_bfromhadt - numeric label if the b is from hadronic top # -1 if not b or not from top # 0 if from leptonic top # 1 if from hadronic top matches = matched_pairs[ij] if len(matches) == 1: mlabel, midx, mdr, mlabel_num, mlabel_num_bfromhadt = matches[ 0] else: #select dR-ordered matches from W, t, b matches_hard = filter(lambda x: x[0] in ["wq", "tb", "hb"], matches) matches_hard = sorted(matches_hard, key=lambda x: x[2]) if len(matches_hard) >= 1: mlabel, midx, mdr, mlabel_num, mlabel_num_bfromhadt = matches_hard[ 0] else: matches_soft = filter(lambda x: x[0] in ["tg", "bg"], matches) matches_soft = sorted(matches_soft, key=lambda x: x[2]) mlabel, midx, mdr, mlabel_num, mlabel_num_bfromhadt = matches_soft[ 0] jet.tth_match_label = mlabel jet.tth_match_index = midx jet.tth_match_dr = mdr jet.tth_match_label_numeric = mlabel_num jet.tth_match_label_bfromhadt = mlabel_num_bfromhadt if mlabel == "wq": event.nMatch_wq += 1 #If this jet is considered to be un-tagged if jet.btagFlag == 0.0: event.nMatch_wq_btag += 1 elif mlabel == "tb": event.nMatch_tb += 1 #If this jet is considered to be b-tagged if jet.btagFlag == 1.0: event.nMatch_tb_btag += 1 elif mlabel == "hb": event.nMatch_hb += 1 if jet.btagFlag == 1.0: event.nMatch_hb_btag += 1 if "debug" in self.conf.general["verbosity"]: autolog( "nSel {0}_{1}_{2} nMatch {3}_{4}_{5} nMatch_btag {6}_{7}_{8}". format( event.nSelected_wq, event.nSelected_tb, event.nSelected_hb, event.nMatch_wq, event.nMatch_tb, event.nMatch_hb, event.nMatch_wq_btag, event.nMatch_tb_btag, event.nMatch_hb_btag, )) if "matching" in self.conf.general["verbosity"]: matches = { "wq": event.l_quarks_w, "tb": event.b_quarks_t, "hb": event.b_quarks_h } for ij, jet in enumerate(event.good_jets): if not matched_pairs.has_key(ij): continue mlabel, midx, mdr, mlabel_num = matched_pairs[ij] autolog("jet match", ij, mlabel, midx, mdr, jet.pt, matches[mlabel][midx].pt) #reco-level tth-matched system spx = 0.0 spy = 0.0 for jet in event.good_jets: if not (jet.tth_match_label is None): p4 = lvec(jet) spx += p4.Px() spy += p4.Py() for lep in event.good_leptons: p4 = lvec(lep) match = False for glep in event.lep_top: p4g = lvec(glep) if p4g.DeltaR(p4) < 0.3: match = True break if match: spx += p4.Px() spy += p4.Py() event.tth_px_reco = spx event.tth_py_reco = spy #Calculate tth recoil #rho = -met - tth_matched event.tth_rho_px_reco = -event.MET.px - event.tth_px_reco event.tth_rho_py_reco = -event.MET.py - event.tth_py_reco #print out gen-level quarks if "input" in self.conf.general["verbosity"]: print "gen Q" for q in event.l_quarks_gen: print q.pt, q.eta, q.phi, q.mass, q.pdgId print "gen B" for q in event.b_quarks_gen: print q.pt, q.eta, q.phi, q.mass, q.pdgId return event
def _process(self, event): #transform the btagCMVA value from -1.0 .. 1.0 to 0.0 .. 1.0 #followed up by a logit transform to get rid of the peaks in the edges for ij in range(len(event.good_jets)): x = event.good_jets[ij].btagCMVA event.good_jets[ij].btagCMVA_log = math.log((1.0 + x)/(1.0 - x)) #btag algos for which to calculate btag LR btagalgos = ["btagCSV", "btagCMVA_log", "btagCMVA"] if self.conf.bran["enabled"]: btagalgos += ["btagCSVRndge4t", "btagCSVInpge4t", "btagCSVRnd3t", "btagCSVInp3t"] jets_for_btag_lr, jet_probs = self.getJetProbs(self.csv_pdfs, event, btagalgos ) btag_likelihood_results = {} btag_likelihood_ratio_results = {} for btagalgo in btagalgos: btag_lr_4b, best_4b_perm = self.btag_likelihood2(jet_probs[btagalgo], 4) btag_lr_2b, best_2b_perm = self.btag_likelihood2(jet_probs[btagalgo], 2) btag_likelihood_results[btagalgo] = (btag_lr_4b, btag_lr_2b, best_4b_perm, best_2b_perm) btag_likelihood_ratio_results[btagalgo] = self.lratio(btag_lr_4b, btag_lr_2b) setattr(event, "jet_perm_btag_lr_" + btagalgo, [event.good_jets.index(j) for j in jets_for_btag_lr[btagalgo]] ) setattr(event, "btag_LR_4b_2b_" + btagalgo, btag_likelihood_ratio_results[btagalgo] ) #default btagger used event.btag_lr_4b = btag_likelihood_results[self.default_bTagAlgo][0] event.btag_lr_2b = btag_likelihood_results[self.default_bTagAlgo][1] event.btag_LR_4b_2b = btag_likelihood_ratio_results[self.default_bTagAlgo] best_4b_perm = btag_likelihood_results[self.default_bTagAlgo][2] # use default btag method always event.buntagged_jets_by_LR_4b_2b = [jets_for_btag_lr[self.default_bTagAlgo][i] for i in best_4b_perm[4:]] event.btagged_jets_by_LR_4b_2b = [jets_for_btag_lr[self.default_bTagAlgo][i] for i in best_4b_perm[0:4]] for i in range(len(event.good_jets)): event.good_jets[i].btagFlag = 0.0 #Jets are untagged according to the b-tagging likelihood ratio permutation if self.conf.jets["untaggedSelection"] == "btagLR": if "debug" in self.conf.general["verbosity"]: autolog("using btagLR for btag/untag jet selection") event.buntagged_jets = event.buntagged_jets_by_LR_4b_2b event.selected_btagged_jets = event.btagged_jets_by_LR_4b_2b #Jets are untagged according to b-discriminatr elif self.conf.jets["untaggedSelection"] == "btagCSV": if "debug" in self.conf.general["verbosity"]: autolog("using btagCSV for btag/untag jet selection") event.buntagged_jets = event.buntagged_jets_bdisc event.selected_btagged_jets = event.btagged_jets_bdisc if "debug" in self.conf.general["verbosity"]: autolog("N(untagged)={0} N(tagged)={1}".format( len(event.buntagged_jets), len(event.selected_btagged_jets) )) btagged = sorted(event.selected_btagged_jets, key=lambda x, self=self: getattr(x, self.default_bTagAlgo) , reverse=True) #Take first 4 most b-tagged jets, these are used for the top and higgs candidates event.selected_btagged_jets_high = btagged[0:4] #any leftover b-tagged jets could be used for the W reconstruction event.selected_btagged_jets_low = btagged[4:] #Set these jets to be used as b-quarks in the MEM #We don't want to use more than 4 b-quarks in the hypothesis for jet in event.selected_btagged_jets_high: #idx = event.good_jets.index(jet) #event.good_jets[idx].btagFlag = 1.0 jet.btagFlag = 1.0 event.passes_btag = len(event.selected_btagged_jets)>=0 if "debug" in self.conf.general["verbosity"]: autolog("BTag selection pass={0}, len(btagged_jets)={1} using the method={2}".format( event.passes_btag, len(event.selected_btagged_jets), self.conf.jets["untaggedSelection"] )) #do category-specific blr cuts cat = "" if event.is_sl: cat += "sl_" if len(event.good_jets) == 4: cat += "j4_" elif len(event.good_jets) == 5: cat += "j5_" elif len(event.good_jets) >= 6: cat += "jge6_" if event.nBCSVM == 2: cat += "t2" elif event.nBCSVM == 3: cat += "t3" elif event.nBCSVM >= 4: cat += "tge4" else: cat = "unknown" elif event.is_dl: cat += "dl_" if len(event.good_jets)==3 and event.nBCSVM==2: cat += "j3_t2" elif len(event.good_jets)==3 and event.nBCSVM==3: cat += "j3_t3" elif len(event.good_jets)>=4 and event.nBCSVM==3: cat += "jge4_t3" elif len(event.good_jets)>=4 and event.nBCSVM==2: cat += "jge4_t2" elif len(event.good_jets)>=4 and event.nBCSVM>=4: cat += "jge4_tge4" else: cat = "unknown" elif event.is_fh: #DS cat += "fh_" if len(event.good_jets) == 7: cat += "j7_" elif len(event.good_jets) == 8: cat += "j8_" elif len(event.good_jets) >= 9: cat += "jge9_" if event.nBCSVM == 3: cat += "t3" elif event.nBCSVM == 4: cat += "t4" elif event.nBCSVM >= 5: cat += "tge5" else: cat = "unknown" else: cat = "unknown" event.category_string = cat blr_cut = self.conf.mem["blr_cuts"].get(cat, -20) if cat != "unknown": event.pass_category_blr = logit(event.btag_LR_4b_2b) > blr_cut else: event.pass_category_blr = False if "debug" in self.conf.general["verbosity"]: autolog("SL/DL category: {0}, pass blr cut {1}: {2}".format( event.category_string, blr_cut, event.pass_category_blr) ) return event
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("MEMAnalyzer started") #Clean up any old MEM state self.vars_to_integrate.clear() self.vars_to_marginalize.clear() self.integrator.next_event() #Initialize members for tree filler event.mem_results_tth = [] event.mem_results_ttbb = [] res = {} if "meminput" in self.conf.general["verbosity"]: print "-----" print "MEM id={0},{1},{2} cat={3} cat_b={4} nj={5} nt={6} nel={7} nmu={8} syst={9}".format( event.input.run, event.input.lumi, event.input.evt, event.is_sl, event.is_dl, event.cat, event.cat_btag, event.numJets, event.nBCSVM, event.n_el_SL, event.n_mu_SL, getattr(event, "systematic", None), getattr(event, "systematic", None), ) for hypo in [MEM.Hypothesis.TTH, MEM.Hypothesis.TTBB]: skipped = [] for confname in self.memkeysToRun: mem_cfg = self.conf.mem_configs[confname] fstate = MEM.FinalState.Undefined if "dl" in mem_cfg.mem_assumptions: fstate = MEM.FinalState.LL elif "sl" in mem_cfg.mem_assumptions: fstate = MEM.FinalState.LH elif "fh" in mem_cfg.mem_assumptions: fstate = MEM.FinalState.HH else: if confname in self.memkeysToRun: raise ValueError( "Need to specify sl, dl of fh in assumptions but got {0}" .format(str(mem_cfg.mem_assumptions))) else: res[(hypo, confname)] = MEM.MEMOutput() continue #if "meminput" in self.conf.general["verbosity"]: if ("meminput" in self.conf.general["verbosity"] or "debug" in self.conf.general["verbosity"]): autolog( "MEMconf={0} fstate={1} MEMCand[l={2} b={3} q={4}] Reco[j={5} b={6} bLR={7}] MEMconf.doCalc={8} event.selection={9} toBeRun={10} isMC={11}" .format(confname, fstate, len(mem_cfg.lepton_candidates(event)), len(mem_cfg.b_quark_candidates(event)), len(mem_cfg.l_quark_candidates(event)), event.numJets, event.nBCSVM, event.btag_LR_4b_2b, mem_cfg.do_calculate(event, mem_cfg), self.conf.mem["selection"](event), confname in self.memkeysToRun, self.cfg_comp.isMC)) #Run MEM if we did not explicitly disable it if (self.conf.mem["calcME"] and mem_cfg.do_calculate(event, mem_cfg) and self.conf.mem["selection"](event) and confname in self.memkeysToRun): print "Integrator::run started hypo={0} conf={1} run:lumi:evt={2}:{3}:{4} {5} blr={6}".format( hypo, confname, event.input.run, event.input.lumi, event.input.evt, event.category_string, event.btag_LR_4b_2b) print "Integrator conf: b={0} l={1}".format( len(mem_cfg.b_quark_candidates(event)), len(mem_cfg.l_quark_candidates(event))) self.configure_mem(event, mem_cfg) r = self.integrator.run(fstate, hypo, self.vars_to_integrate, self.vars_to_marginalize) print "Integrator::run done hypo={0} conf={1} cat={2}".format( hypo, confname, event.cat) #DS res[(hypo, confname)] = r else: skipped += [confname] r = MEM.MEMOutput() res[(hypo, confname)] = r if "meminput" in self.conf.general["verbosity"]: print "skipped confs", skipped #Add MEM results to event for key in self.memkeysToRun: for (hypo_name, hypo) in [("tth", MEM.Hypothesis.TTH), ("ttbb", MEM.Hypothesis.TTBB)]: mem_res = res[(hypo, key)] setattr(event, "mem_{0}_{1}".format(hypo_name, key), mem_res) #Create MEM permutations perms = [] for iperm in range(mem_res.num_perm): perm = mem_res.permutation_indexes[iperm] v_p = normalize_proba( [v for v in mem_res.permutation_probas[iperm]]) v_p_tf = normalize_proba([ v for v in mem_res.permutation_probas_transfer[iperm] ]) v_p_me = normalize_proba( [v for v in mem_res.permutation_probas_me[iperm]]) mem_perm = MEMPermutation( iperm, [_p for _p in perm], np.mean(v_p), np.std(v_p), np.mean(v_p_tf), np.std(v_p_tf), np.mean(v_p_me), np.std(v_p_me), ) perms += [mem_perm] setattr(event, "mem_{0}_{1}_perm".format(hypo_name, key), perms) #print out the JSON format for the standalone integrator for confname in self.memkeysToRun: mem_cfg = self.mem_configs[confname] if "commoninput" in self.conf.general[ "verbosity"] and mem_cfg.do_calculate(event, mem_cfg): self.printInputs(event, confname) event.passes_mem = True return event
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("BTagRandomizer started") event.b_ran_results = [] for jet in event.good_jets: add_obj( self.rnd, MEM.ObjectType.Jet, p4s=(jet.pt, jet.eta, jet.phi, jet.mass), obs_dict={ MEM.Observable.BTAG: getattr(jet, self.algo) > self.btagWP, MEM.Observable.PDGID: jet.mcFlavour, MEM.Observable.CSV: getattr(jet, self.algo) } ) run_vec_jet_categories = vectype() posrun = [] pos = -1 for jc in self.vec_jet_categories: pos += 1 jc.seed = (event.input.evt + event.input.lumi*jc.tag) if jc.ntags_l <= event.numJets: run_vec_jet_categories.push_back(jc) posrun.append( pos ) if self.conf.bran["enabled"]: ret = self.rnd.run_all(run_vec_jet_categories) pos = -1 for jc in self.vec_jet_categories: pos += 1 catname = jc.name_tag catid = jc.tag out = MEM.BTagRandomizerOutput() wasrun = pos in posrun if wasrun: out = ret[ posrun.index(pos) ] setattr(event, "b_rnd_results_"+catname, [out.p, out.ntoys, out.pass_rnd, out.tag_id] ) setattr(event, "b_inp_results_"+catname, [1.0, 0, getattr(out,"pass",0), out.tag_id] ) else: setattr(event, "b_rnd_results_"+catname, [0,0,0,0] ) setattr(event, "b_inp_results_"+catname, [0,0,0,0] ) for j in range(event.numJets): inpval = getattr(event.good_jets[j], self.algo) rndval = inpval if wasrun: inpval = out.input_btag[j] rndval = out.rnd_btag[j] setattr(event.good_jets[j], "btagCSVInp"+catname, inpval ) setattr(event.good_jets[j], "btagCSVRnd"+catname, rndval ) countTags = 0 for jet in event.good_jets: if wasrun and getattr( jet, "btagCSVRnd"+catname ) > self.btagWP: countTags += 1 setattr(event, "nBCSVMRnd"+catname, countTags) self.rnd.next_event(); event.passes_bran = True return event
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("MECategoryAnalyzer started") cat = "NOCAT" pass_btag_csv = (self.conf.jets["untaggedSelection"] == "btagCSV" and len(event.selected_btagged_jets_high) >= 4) #Here we define if an event was of high-btag multiplicity cat_btag = "NOCAT" if event.pass_category_blr or pass_btag_csv: cat_btag = "H" else: cat_btag = "L" if event.is_sl: #at least 6 jets, if 6, Wtag in [60,100], if more Wtag in [72,94] if ((len(event.good_jets) == 6 and event.Wmass >= 60 and event.Wmass < 100) or (len(event.good_jets) > 6 and event.Wmass >= 72 and event.Wmass < 94)): cat = "cat1" #W-tagger fills wquark_candidate_jets #at least 6 jets, no W-tag elif len(event.good_jets) >= 6: cat = "cat2" #one W daughter missing elif len(event.good_jets) == 5: event.wquark_candidate_jets = event.buntagged_jets cat = "cat3" elif event.is_dl and len(event.good_jets) >= 4: #event.wquark_candidate_jets = [] event.wquark_candidate_jets = event.buntagged_jets cat = "cat6" elif event.is_fh: #exactly 8 jets, Wtag in [60,100] if (len(event.good_jets) == 8 and event.Wmass >= 60 and event.Wmass < 100): #event.wquark_candidate_jets = event.buntagged_jets + event.selected_btagged_jets_low #DS adds 5th,6th,... btags if (len(event.selected_btagged_jets_high) == 4): cat = "cat8" elif (len(event.selected_btagged_jets_high) == 3): cat = "cat10" #exactly 7 jets, Wtag in [60,100] if (len(event.good_jets) == 7 and event.Wmass >= 60 and event.Wmass < 100): #event.wquark_candidate_jets = event.buntagged_jets + event.selected_btagged_jets_low if (len(event.selected_btagged_jets_high) == 4): cat = "cat7" elif (len(event.selected_btagged_jets_high) == 3): cat = "cat11" #exactly 9 jets, Wtag in [72,94] if (len(event.good_jets) == 9 and event.Wmass >= 72 and event.Wmass < 94): #event.wquark_candidate_jets = event.buntagged_jets + event.selected_btagged_jets_low if (len(event.selected_btagged_jets_high) == 4): cat = "cat9" elif (len(event.selected_btagged_jets_high) == 3): cat = "cat12" event.cat = cat event.cat_btag = cat_btag event.catn = self.cat_map.get(cat, -1) event.cat_btag_n = self.btag_cat_map.get(cat_btag, -1) #always pass ME category analyzer event.passes_mecat = True return event
def configure_mem(self, event, mem_cfg): self.integrator.set_cfg(mem_cfg.cfg) self.vars_to_integrate.clear() self.vars_to_marginalize.clear() self.integrator.next_event() set_integration_vars(self.vars_to_integrate, self.vars_to_marginalize, mem_cfg.mem_assumptions) bquarks = sorted(list(mem_cfg.b_quark_candidates(event)), key=lambda x: x.pt, reverse=True) if len(bquarks) > mem_cfg.maxBJets: autolog("More than {0} b-quarks supplied, dropping last {1} from MEM".format( mem_cfg.maxBJets, len(bquarks) - mem_cfg.maxBJets) ) for q in bquarks[mem_cfg.maxBJets:]: print "Dropping jet", q.pt, q.eta bquarks = bquarks[:mem_cfg.maxBJets] lquarks = sorted(list(mem_cfg.l_quark_candidates(event)), key=lambda x: x.pt, reverse=True) if len(lquarks) > mem_cfg.maxLJets: autolog("More than {0} l-quarks supplied, dropping last {1} from MEM".format( mem_cfg.maxLJets, len(lquarks) - mem_cfg.maxLJets) ) for q in lquarks[mem_cfg.maxLJets:]: print "Dropping jet", q.pt, q.eta lquarks = lquarks[:mem_cfg.maxLJets] ##Only take up to 4 candidates, otherwise runtimes become too great for jet in bquarks + lquarks: add_obj( self.integrator, MEM.ObjectType.Jet, p4s=(jet.pt, jet.eta, jet.phi, jet.mass), obs_dict={ MEM.Observable.BTAG: jet.btagFlag, #MEM.Observable.CSV: getattr(jet, mem_cfg.btagMethod, -1), #MEM.Observable.PDGID: getattr(jet, "PDGID", 0) }, tf_dict={ MEM.TFType.bReco: jet.tf_b, MEM.TFType.qReco: jet.tf_l, } ) if "meminput" in self.conf.general["verbosity"]: print "memBQuark" if jet in bquarks else "memLQuark",\ jet.pt, jet.eta, jet.phi, jet.mass,\ ", Flag: ", jet.btagFlag,\ ", CSV: ", getattr(jet, mem_cfg.btagMethod, -1),\ ", PDGID: ", getattr(jet, "PDGID", -1),\ ", Match: ", jet.tth_match_label, jet.tth_match_index for lep in mem_cfg.lepton_candidates(event): add_obj( self.integrator, MEM.ObjectType.Lepton, p4s=(lep.pt, lep.eta, lep.phi, lep.mass), obs_dict={MEM.Observable.CHARGE: lep.charge}, ) if "meminput" in self.conf.general["verbosity"]: print "memLepton", lep.pt, lep.eta, lep.phi, lep.mass, lep.charge met_cand = mem_cfg.met_candidates(event) if "meminput" in self.conf.general["verbosity"]: print "memMET", met_cand.pt, met_cand.phi add_obj( self.integrator, MEM.ObjectType.MET, #MET is caused by massless object p4s=(met_cand.pt, 0, met_cand.phi, 0), )
def _process(self, event): event.passes_subjet = True if "debug" in self.conf.general["verbosity"]: autolog("SubjetAnalyzer started") if "subjet" in self.conf.general["verbosity"]: print 'Printing from SubjetAnalyzer! iEv = {0}'.format(event.iEv) # Is set to True only after the event passed all criteria setattr( event, 'PassedSubjetAnalyzer', False ) # Create two new lists for selected_btagged_jets and wquark_candidate_jets # Needs to be done here because the lists are needed in the mem config setattr( event, 'boosted_bjets', [] ) setattr( event, 'boosted_ljets', [] ) setattr( event, 'topCandidate', [] ) setattr( event, 'topCandidatesSync', [] ) setattr( event, 'othertopCandidate', [] ) setattr( event, 'higgsCandidate', [] ) setattr( event, 'higgsCandidateForSync', [] ) event.n_bjets = len( event.selected_btagged_jets_high ) event.n_ljets = len( list( event.wquark_candidate_jets ) ) ######################################## # Minimal event suitability: # - Needs to be single leptonic # - At least 1 httCandidate ######################################## # Check if the event is single leptonic if not (event.is_sl or event.is_fh): #LC return event # Get the top candidates # ====================================== # Keep track of number of httCandidates that passed the cut setattr( event, 'nhttCandidate', len( event.httCandidates ) ) setattr( event, 'nhttCandidate_aftercuts', 0 ) # Just run normal mem if there is no httCandidate present # Check if there is an httCandidate # if len( event.httCandidates ) == 0: # return event # All HTT candidates for sync all_tops = [] for candidate in event.httCandidates: all_tops.append( copy.deepcopy(candidate) ) # Match the top to a fat jet # - Copies bbtag and tau_N, calculates n_subjettiness # - DOES NOT apply the n_subjettiness cut all_tops = self.Match_top_to_fatjet( event, all_tops, False ) for top in all_tops: top.fj_index = event.FatjetCA15ungroomed.index(top.matched_fatjet) # Sort by which ungroomed fj they are matched to all_tops = sorted(all_tops, key=lambda x: x.fj_index ) # Apply the cuts on the httCandidate tops = [] for candidate in event.httCandidates: if self.Apply_Cut_criteria( candidate ): tops.append( copy.deepcopy(candidate) ) # Match the top to a fat jet # - Copies bbtag and tau_N, calculates n_subjettiness # - Applies the n_subjettiness cut tops = self.Match_top_to_fatjet( event, tops, True ) other_tops = [] # Calculate delR with the lepton for all tops that survived the cut if event.is_sl: #LC for top in tops + all_tops: setattr( top, 'delR_lepton' , self.Get_DeltaR_two_objects( top, event.good_leptons[0] ) ) else: for top in tops + all_tops: setattr( top, 'delR_lepton' , -1 ) # Keep track of how many httCandidates passed event.nhttCandidate_aftercuts = len( tops ) #Find the best hadronic gen top match for each top candidate if self.cfg_comp.isMC: gentops = getattr(event, "genTopHad", []) if len(gentops)>0: for topcandidate in tops: lv1 = lvec(topcandidate) drs = [] for igentop, gentop in enumerate(gentops): lv2 = lvec(gentop) drs += [(lv1.DeltaR(lv2), gentop, igentop)] drs = sorted(drs, key=lambda x: x[0]) best = drs[0] topcandidate.genTopHad_dr = best[0] topcandidate.genTop = best[1] topcandidate.genTopHad_index = best[2] # Just run normal mem if there is no httCandidate surviving the cuts # Check if any candidates survived the cutoff criteria # if len(tops) == 0: # return event # If exactly 1 survived, simply continue with that candidate other_top_present = False top = None if len(tops) == 0: other_top_present = False elif len(tops) == 1: top = tops[0] other_top_present = False # If more than 1 candidate survived the cutoff criteria, choose the # one whose delR with the lepton was biggest else: if event.is_sl: #LC tops = sorted( tops, key=lambda x: -x.delR_lepton ) else: tops = sorted( tops, key=lambda x: x.pt) other_top_present = True top = tops[0] other_tops = tops[1:] if "subjet" in self.conf.general["verbosity"]: print "Number of top candidates ", len(tops) # Get a Higgs candidate # ====================================== #Types of fatjets to match to Higgs candidate fatjets_to_match = ["softdropz2b1", "softdrop", "pruned", "subjetfiltered"] extra_higgs_vars = ["mass", "nallsubjets", "sj1pt", "sj1eta", "sj1phi", "sj1mass", "sj1btag", "sj2pt", "sj2eta", "sj2phi", "sj2mass", "sj2btag", "sj3pt", "sj3eta", "sj3phi", "sj3mass", "sj3btag", "sj12mass"] # TODO: # -add groomed n-subjettiness for fatjet_name in fatjets_to_match: self.Add_Higgs_Subjets_To_Fatjet(event, fatjet_name) higgs_present = False higgsCandidates = [] for fatjet in event.FatjetCA15ungroomed: # Turned off for now. TODO: Revisit Higgs/Top overlap removal # # Choose only fatjets that were not HTTv2 candidates for the higgs reco # # Check if the fatjet is not already matched to the chosen top candidate # if top and hasattr(fatjet, 'matched_top') and fatjet == top.matched_fatjet: # continue fatjet.n_subjettiness = -1 if fatjet.tau1 > 0: fatjet.n_subjettiness = fatjet.tau2 / fatjet.tau1 if top: fatjet.dr_top = self.Get_DeltaR_two_objects(fatjet, top) #set default extra variables for all fatjet types for fatjetkind in fatjets_to_match: for var in extra_higgs_vars: setattr(fatjet, var + "_" + fatjetkind, -9999) genhiggs = getattr(event, "GenHiggsBoson", []) #match higgs candidate to generated higgs if self.cfg_comp.isMC and len(genhiggs) >= 1: lv1 = lvec(fatjet) lv2 = lvec(genhiggs[0]) fatjet.dr_genHiggs = lv1.DeltaR(lv2) higgsCandidates.append( fatjet ) higgs_present = True # Sort by pT # TODO: for now. Revisit and change to subjet b-tag/bbtag we decide on higgsCandidates = sorted( higgsCandidates, key=lambda x: -x.pt ) # Match higgs candidates to various fat jets for fatjetkind in fatjets_to_match: nmatch = self.Match_two_lists( higgsCandidates, 'higgs', getattr(event, "FatjetCA15" + fatjetkind), 'fatjet_' + fatjetkind, R_cut = self.R_cut_fatjets ) # Add properties of the matched fatjet to the higgs candidate for higgsCandidate in higgsCandidates: for fatjetkind in fatjets_to_match: matchjet = getattr(higgsCandidate, "matched_fatjet_" + fatjetkind, None) if matchjet != None: for var in extra_higgs_vars: if hasattr(matchjet,var): setattr(higgsCandidate, var + "_" + fatjetkind, getattr(matchjet,var)) ######################################## # Get the lists of particles: quarks, jets and subjets ######################################## # Get the subjets from the httCandidate # - Also sets transfer functions as attributes # - Returns subjets ordered by decreasing btag # - First subjet has btagFlag==1.0, the other two btagFlag==0.0 top_subjets = self.Get_Subjets( top ) if "subjet" in self.conf.general["verbosity"]: print "subjets" for subjet in top_subjets: print subjet if other_top_present: for top in other_tops: self.Get_Subjets( top ) # Set 'PDGID' to 1 for light, and to 5 for b for subjet in top_subjets: if subjet.btagFlag == 1.0: setattr( subjet, 'PDGID', 5 ) if subjet.btagFlag == 0.0: setattr( subjet, 'PDGID', 1 ) # Create two new lists for btagged_jets and wquark_candidate_jets in the # original events if event.is_sl: #LC reco_btagged_jets = copy.deepcopy( event.selected_btagged_jets_high ) reco_ltagged_jets = copy.deepcopy( list( event.wquark_candidate_jets ) ) else: #LC reco_ltagged_jets = event.buntagged_jets_bdisc reco_btagged_jets = event.btagged_jets_bdisc if len(tops) > 0: top_subjets = self.Get_Subjets( top ) if "subjet" in self.conf.general["verbosity"]: print "subjets" for subjet in top_subjets: print subjet if other_top_present: for top in other_tops: self.Get_Subjets( top ) # Set 'PDGID' to 1 for light, and to 5 for b # FIXME: do not use PDGID currently, as it ONLY works with the HEPTopTagger perm pruning strat #for subjet in top_subjets: # if subjet.btagFlag == 1.0: setattr( subjet, 'PDGID', 5 ) # if subjet.btagFlag == 0.0: setattr( subjet, 'PDGID', 1 ) # Create two new lists for btagged_jets and wquark_candidate_jets in the # original events reco_btagged_jets = copy.deepcopy( event.selected_btagged_jets_high ) reco_ltagged_jets = copy.deepcopy( list( event.wquark_candidate_jets ) ) for jet in reco_btagged_jets: setattr( jet, 'btag', getattr(jet,self.btagAlgo) ) setattr( jet, 'btagFlag', 1.0 ) #setattr( jet, 'PDGID', 0 ) for jet in reco_ltagged_jets: setattr( jet, 'btag', getattr(jet,self.btagAlgo) ) setattr( jet, 'btagFlag', 0.0 ) #setattr( jet, 'PDGID', 0 ) ######################################## # Matching ######################################## # Whenever a subjet has a 'match' (dR < dR_cut), the matched object should # excluded from the event # Match subjet to a bjet n_excluded_bjets = self.Match_two_lists( top_subjets, 'top_subjet', reco_btagged_jets, 'bjet' ) # Match subjet to a ljet n_excluded_ljets = self.Match_two_lists( top_subjets , 'top_subjet', reco_ltagged_jets, 'ljet' ) if "subjet" in self.conf.general["verbosity"]: print "subjet nMatchB={0} nMatchL={1}".format(n_excluded_bjets, n_excluded_ljets) #FIXME: Unify this for SL/DL/FH #from FH branch # # Stop adding after 4 b-jets # if event.is_sl:#LC # if len(boosted_bjets) == 4: break # event.PassedSubjetAnalyzer = True # # if event.is_fh: #LC: also add other light jets # for ljet in reco_ltagged_jets: # # Check if the l-jet is not excluded # if not hasattr( ljet, 'matched_top_subjet' ): # boosted_ljets.append( ljet ) # # # # # # If too many events are excluded, just run the default hypothesis # else: # if "subjet" in self.conf.general["verbosity"]: # print "[SubjetAnalyzer] subjet has too many overlaps, using reco" # boosted_bjets = reco_btagged_jets # boosted_ljets = reco_ltagged_jets # event.PassedSubjetAnalyzer = False #======= end from FH branch # In case of double matching, choose the match with lowest delR # (This is not expected to happen often) for subjet in top_subjets: if hasattr( subjet, 'matched_bjet' ) and \ hasattr( subjet, 'matched_ljet' ) : print '[SubjetAnalyzer] Double match detected' if subjet.matched_bjet_delR < subjet.matched_ljet_delR: del subjet.matched_ljet del subjet.matched_ljet_delR n_excluded_bjets -= 1 else: del subjet.matched_bjet del subjet.matched_bjet_delR n_excluded_ljets -= 1 ######################################## # Modifying the bjets and ljets lists ######################################## boosted_bjets = [] boosted_ljets = [] if n_excluded_bjets <= 1: if "subjet" in self.conf.general["verbosity"]: print "subjet replacing" # Add the subjets to the final output lists first for subjet in top_subjets: if subjet.btagFlag == 1.0: boosted_bjets.append( subjet ) if subjet.btagFlag == 0.0: boosted_ljets.append( subjet ) # Sort tl btagged jets by decreasing btag (to be sure, but should # already be done in previous analyzer) # Only resolved b-jets reco_btagged_jets = sorted( reco_btagged_jets, key=lambda x: -x.btag ) # Add up to 4 reco btagged jets to the output lists for bjet in reco_btagged_jets: # Check if the b-jet is not excluded if not hasattr( bjet, 'matched_top_subjet' ): boosted_bjets.append( bjet ) # Stop adding after 4 b-jets if len(boosted_bjets) == 4: break event.PassedSubjetAnalyzer = True # If too many events are excluded, just run the default hypothesis else: if "subjet" in self.conf.general["verbosity"]: print "[SubjetAnalyzer] subjet has too many overlaps, using reco" boosted_bjets = reco_btagged_jets boosted_ljets = reco_ltagged_jets event.PassedSubjetAnalyzer = False ######################################## # Write to event ######################################## # Store output lists in event event.higgsCandidate = higgsCandidates all_tops_to_add = [] # Add top matched to leading fatjet OR dummy for top in all_tops: if top.fj_index == 0: all_tops_to_add.append(top) break if len(all_tops_to_add) == 0: all_tops_to_add.append(DummyTop()) # Add top matched to sub-leading fatjet OR dummy for top in all_tops: if top.fj_index == 1: all_tops_to_add.append( top) break if len(all_tops_to_add) == 1: all_tops_to_add.append(DummyTop()) event.topCandidatesSync = all_tops_to_add if len(tops)>0: event.topCandidate = [ top ] event.othertopCandidate = other_tops event.boosted_bjets = boosted_bjets event.boosted_ljets = boosted_ljets event.n_boosted_bjets = len( boosted_bjets ) event.n_boosted_ljets = len( boosted_ljets ) event.n_excluded_bjets = n_excluded_bjets event.n_excluded_ljets = n_excluded_ljets #pdb.set_trace() if "subjet" in self.conf.general["verbosity"]: print '[SubjetAnalyzer] Exiting SubjetAnalyzer! event.PassedSubjetAnalyzer = {0}'.format( event.PassedSubjetAnalyzer ) ######################################## # Matching to Gen top ########################################### event.n_matched_TTgentop = -1 event.matched_TTgentop_pt = -1 event.n_matched_TTgenb = -1 event.n_matched_TTgenW = -1 if len(tops)>0: self.Do_GenTop_Matching(event) return event ######################################## # Quark Matching ######################################## # This section is only useful for truth-level comparison, and can be turned # off if this is not needed. # Do_Quark_Matching( event ) sets number of matches with quarks as branches # in the event, but these branches do not have to be filled (they will be # automatically set to -1 in the final output root file). self.Do_Quark_Matching( event )
def _process(self, event): if "debug" in self.conf.general["verbosity"]: autolog("MECategoryAnalyzer started") cat = "NOCAT" pass_btag_csv = (self.conf.jets["untaggedSelection"] == "btagCSV" and len(event.selected_btagged_jets_high) >= 4 ) #Here we define if an event was of high-btag multiplicity cat_btag = "NOCAT" if event.pass_category_blr or pass_btag_csv: cat_btag = "H" else: cat_btag = "L" if event.is_sl: #at least 6 jets, if 6, Wtag in [60,100], if more Wtag in [72,94] if ((len(event.good_jets) == 6 and event.Wmass >= 60 and event.Wmass < 100) or (len(event.good_jets) > 6 and event.Wmass >= 72 and event.Wmass < 94)): cat = "cat1" #W-tagger fills wquark_candidate_jets #at least 6 jets, no W-tag elif len(event.good_jets) >= 6: cat = "cat2" #one W daughter missing elif len(event.good_jets) == 5: event.wquark_candidate_jets = event.buntagged_jets cat = "cat3" elif event.is_dl and len(event.good_jets)>=4: #event.wquark_candidate_jets = [] event.wquark_candidate_jets = event.buntagged_jets cat = "cat6" elif event.is_fh: #exactly 8 jets, Wtag in [60,100] if (len(event.good_jets) == 8 and event.Wmass >= 60 and event.Wmass < 100): #event.wquark_candidate_jets = event.buntagged_jets + event.selected_btagged_jets_low #DS adds 5th,6th,... btags if(len(event.selected_btagged_jets_high) == 4): cat = "cat8" elif(len(event.selected_btagged_jets_high) == 3): cat = "cat10" #exactly 7 jets, Wtag in [60,100] if (len(event.good_jets) == 7 and event.Wmass >= 60 and event.Wmass < 100): #event.wquark_candidate_jets = event.buntagged_jets + event.selected_btagged_jets_low if(len(event.selected_btagged_jets_high) == 4): cat = "cat7" elif(len(event.selected_btagged_jets_high) == 3): cat = "cat11" #exactly 9 jets, Wtag in [72,94] if (len(event.good_jets) == 9 and event.Wmass >= 72 and event.Wmass < 94): #event.wquark_candidate_jets = event.buntagged_jets + event.selected_btagged_jets_low if(len(event.selected_btagged_jets_high) == 4): cat = "cat9" elif(len(event.selected_btagged_jets_high) == 3): cat = "cat12" event.cat = cat event.cat_btag = cat_btag event.catn = self.cat_map.get(cat, -1) event.cat_btag_n = self.btag_cat_map.get(cat_btag, -1) #always pass ME category analyzer event.passes_mecat = True return event
def _process(self, event): event.passes_subjet = True if "debug" in self.conf.general["verbosity"]: autolog("SubjetAnalyzer started") if "subjet" in self.conf.general["verbosity"]: print 'Printing from SubjetAnalyzer! iEv = {0}'.format(event.iEv) # Is set to True only after the event passed all criteria setattr( event, 'PassedSubjetAnalyzer', False ) # Create two new lists for selected_btagged_jets and wquark_candidate_jets # Needs to be done here because the lists are needed in the mem config setattr( event, 'boosted_bjets', [] ) setattr( event, 'boosted_ljets', [] ) setattr( event, 'topCandidate', [] ) setattr( event, 'topCandidatesSync', [] ) setattr( event, 'othertopCandidate', [] ) setattr( event, 'higgsCandidate', [] ) setattr( event, 'higgsCandidateForSync', [] ) event.n_bjets = len( event.selected_btagged_jets_high ) event.n_ljets = len( list( event.wquark_candidate_jets ) ) ######################################## # Minimal event suitability: # - Needs to be single leptonic # - At least 1 httCandidate ######################################## # Check if the event is single leptonic or FH # for SYNC: REMOVE this cut #if not (event.is_sl or event.is_fh): #LC # return event # Get the top candidates # ====================================== # Keep track of number of httCandidates that passed the cut setattr( event, 'nhttCandidate', len( event.httCandidates ) ) setattr( event, 'nhttCandidate_aftercuts', 0 ) # Just run normal mem if there is no httCandidate present # Check if there is an httCandidate # if len( event.httCandidates ) == 0: # return event # All HTT candidates for sync all_tops = [] for candidate in event.httCandidates: # Veto tops unless all subjets pass jetID if not candidate.subjetIDPassed: continue # (optional eta cut) #if abs(candidate.eta) < 2.0: all_tops.append( copy.deepcopy(candidate) ) # TODO: Add eta cut also to analysis tops # Match the top to a fat jet # - Copies bbtag and tau_N, calculates n_subjettiness # - DOES NOT apply the n_subjettiness cut all_tops = self.Match_top_to_fatjet( event, all_tops, False ) for top in all_tops: top.fj_index = event.FatjetCA15ungroomed.index(top.matched_fatjet) # Sort by which ungroomed fj they are matched to all_tops = sorted(all_tops, key=lambda x: x.fj_index ) # Apply the cuts on the httCandidate tops = [] for candidate in event.httCandidates: if self.Apply_Cut_criteria( candidate ): tops.append( copy.deepcopy(candidate) ) # Match the top to a fat jet # - Copies bbtag and tau_N, calculates n_subjettiness # - Applies the n_subjettiness cut tops = self.Match_top_to_fatjet( event, tops, True ) other_tops = [] # Calculate delR with the lepton for all tops that survived the cut if event.is_sl: #LC for top in tops + all_tops: setattr( top, 'delR_lepton' , self.Get_DeltaR_two_objects( top, event.good_leptons[0] ) ) else: for top in tops + all_tops: setattr( top, 'delR_lepton' , -1 ) # Keep track of how many httCandidates passed event.nhttCandidate_aftercuts = len( tops ) #Find the best hadronic gen top match for each top candidate if self.cfg_comp.isMC: gentops = getattr(event, "genTopHad", []) if len(gentops)>0: for topcandidate in tops: lv1 = lvec(topcandidate) drs = [] for igentop, gentop in enumerate(gentops): lv2 = lvec(gentop) drs += [(lv1.DeltaR(lv2), gentop, igentop)] drs = sorted(drs, key=lambda x: x[0]) best = drs[0] topcandidate.genTopHad_dr = best[0] topcandidate.genTop = best[1] topcandidate.genTopHad_index = best[2] # Just run normal mem if there is no httCandidate surviving the cuts # Check if any candidates survived the cutoff criteria # if len(tops) == 0: # return event # If exactly 1 survived, simply continue with that candidate other_top_present = False top = None if len(tops) == 0: other_top_present = False elif len(tops) == 1: top = tops[0] other_top_present = False # If more than 1 candidate survived the cutoff criteria, choose the # one whose delR with the lepton was biggest else: if event.is_sl: #LC tops = sorted( tops, key=lambda x: -x.delR_lepton ) else: tops = sorted( tops, key=lambda x: x.pt) other_top_present = True top = tops[0] other_tops = tops[1:] if "subjet" in self.conf.general["verbosity"]: print "Number of top candidates ", len(tops) # Get a Higgs candidate # ====================================== #Types of fatjets to match to Higgs candidate fatjets_to_match = ["softdropz2b1", "softdrop", "softdropz2b1filt", "softdropfilt", "pruned", "subjetfiltered"] extra_higgs_vars = ["mass", "nallsubjets", "sj1pt", "sj1eta", "sj1phi", "sj1mass", "sj1btag", "sj2pt", "sj2eta", "sj2phi", "sj2mass", "sj2btag", "sj3pt", "sj3eta", "sj3phi", "sj3mass", "sj3btag", # only calc for subjetfiltered "sj12masspt", "sj12massb", "sj123masspt", # only calc for subjetfiltered "secondbtag", # only calc for subjetfiltered ] for fatjet_name in fatjets_to_match: self.Add_Higgs_Subjets_To_Fatjet(event, fatjet_name) higgs_present = False higgsCandidates = [] for fatjet in event.FatjetCA15ungroomed: # Turned off for now. TODO: Revisit Higgs/Top overlap removal # # Choose only fatjets that were not HTTv2 candidates for the higgs reco # # Check if the fatjet is not already matched to the chosen top candidate # if top and hasattr(fatjet, 'matched_top') and fatjet == top.matched_fatjet: # continue fatjet.n_subjettiness = -1 if fatjet.tau1 > 0: fatjet.n_subjettiness = fatjet.tau2 / fatjet.tau1 if top: fatjet.dr_top = self.Get_DeltaR_two_objects(fatjet, top) #set default extra variables for all fatjet types for fatjetkind in fatjets_to_match: for var in extra_higgs_vars: setattr(fatjet, var + "_" + fatjetkind, -9999) if self.cfg_comp.isMC: #match higgs candidate to generated higgs genhiggs = getattr(event, "GenHiggsBoson", []) if len(genhiggs)>0: lv1 = lvec(fatjet) lv2 = lvec(genhiggs[0]) fatjet.dr_genHiggs = lv1.DeltaR(lv2) #match higgs candidate to generated tops gentops = [x for x in getattr(event, "GenTop", []) if x.pt>self.GenTop_pt_cut] if len(gentops)>0: lv1 = lvec(fatjet) fatjet.dr_genTop = min([lv1.DeltaR(lvec(x)) for x in gentops]) higgsCandidates.append( fatjet ) higgs_present = True # Match higgs candidates to various fat jets for fatjetkind in fatjets_to_match: nmatch = self.Match_two_lists( higgsCandidates, 'higgs', getattr(event, "FatjetCA15" + fatjetkind), 'fatjet_' + fatjetkind, R_cut = self.R_cut_fatjets ) # Add properties of the matched fatjet to the higgs candidate for higgsCandidate in higgsCandidates: for fatjetkind in fatjets_to_match: matchjet = getattr(higgsCandidate, "matched_fatjet_" + fatjetkind, None) if matchjet != None: for var in extra_higgs_vars: if hasattr(matchjet,var): setattr(higgsCandidate, var + "_" + fatjetkind, getattr(matchjet,var)) # Sort higgs candidates by pt # We store all of them, so it does not really matter fow now higgsCandidates = sorted( higgsCandidates, key=lambda x: -x.pt ) ######################################## # Get the lists of particles: quarks, jets and subjets ######################################## # Get the subjets from the httCandidate # - Also sets transfer functions as attributes # - Returns subjets ordered by decreasing btag # - First subjet has btagFlag==1.0, the other two btagFlag==0.0 top_subjets = self.Get_Subjets( top ) if "subjet" in self.conf.general["verbosity"]: print "subjets" for subjet in top_subjets: print subjet if other_top_present: for top in other_tops: self.Get_Subjets( top ) # Set 'PDGID' to 1 for light, and to 5 for b for subjet in top_subjets: if subjet.btagFlag == 1.0: setattr( subjet, 'PDGID', 5 ) if subjet.btagFlag == 0.0: setattr( subjet, 'PDGID', 1 ) # Create two new lists for btagged_jets and wquark_candidate_jets in the # original events if event.is_sl: #LC reco_btagged_jets = copy.deepcopy( event.selected_btagged_jets_high ) reco_ltagged_jets = copy.deepcopy( list( event.wquark_candidate_jets ) ) else: #LC reco_ltagged_jets = event.buntagged_jets_bdisc reco_btagged_jets = event.btagged_jets_bdisc if len(tops) > 0: top_subjets = self.Get_Subjets( top ) if "subjet" in self.conf.general["verbosity"]: print "subjets" for subjet in top_subjets: print subjet if other_top_present: for top in other_tops: self.Get_Subjets( top ) # Set 'PDGID' to 1 for light, and to 5 for b # FIXME: do not use PDGID currently, as it ONLY works with the HEPTopTagger perm pruning strat #for subjet in top_subjets: # if subjet.btagFlag == 1.0: setattr( subjet, 'PDGID', 5 ) # if subjet.btagFlag == 0.0: setattr( subjet, 'PDGID', 1 ) # Create two new lists for btagged_jets and wquark_candidate_jets in the # original events reco_btagged_jets = copy.deepcopy( event.selected_btagged_jets_high ) reco_ltagged_jets = copy.deepcopy( list( event.wquark_candidate_jets ) ) for jet in reco_btagged_jets: setattr( jet, 'btag', getattr(jet,self.btagAlgo) ) setattr( jet, 'btagFlag', 1.0 ) #setattr( jet, 'PDGID', 0 ) for jet in reco_ltagged_jets: setattr( jet, 'btag', getattr(jet,self.btagAlgo) ) setattr( jet, 'btagFlag', 0.0 ) #setattr( jet, 'PDGID', 0 ) ######################################## # Matching ######################################## # Whenever a subjet has a 'match' (dR < dR_cut), the matched object should # excluded from the event # Match subjet to a bjet n_excluded_bjets = self.Match_two_lists( top_subjets, 'top_subjet', reco_btagged_jets, 'bjet' ) # Match subjet to a ljet n_excluded_ljets = self.Match_two_lists( top_subjets , 'top_subjet', reco_ltagged_jets, 'ljet' ) if "subjet" in self.conf.general["verbosity"]: print "subjet nMatchB={0} nMatchL={1}".format(n_excluded_bjets, n_excluded_ljets) #FIXME: Unify this for SL/DL/FH #from FH branch # # Stop adding after 4 b-jets # if event.is_sl:#LC # if len(boosted_bjets) == 4: break # event.PassedSubjetAnalyzer = True # # if event.is_fh: #LC: also add other light jets # for ljet in reco_ltagged_jets: # # Check if the l-jet is not excluded # if not hasattr( ljet, 'matched_top_subjet' ): # boosted_ljets.append( ljet ) # # # # # # If too many events are excluded, just run the default hypothesis # else: # if "subjet" in self.conf.general["verbosity"]: # print "[SubjetAnalyzer] subjet has too many overlaps, using reco" # boosted_bjets = reco_btagged_jets # boosted_ljets = reco_ltagged_jets # event.PassedSubjetAnalyzer = False #======= end from FH branch # In case of double matching, choose the match with lowest delR # (This is not expected to happen often) for subjet in top_subjets: if hasattr( subjet, 'matched_bjet' ) and \ hasattr( subjet, 'matched_ljet' ) : print '[SubjetAnalyzer] Double match detected' if subjet.matched_bjet_delR < subjet.matched_ljet_delR: del subjet.matched_ljet del subjet.matched_ljet_delR n_excluded_bjets -= 1 else: del subjet.matched_bjet del subjet.matched_bjet_delR n_excluded_ljets -= 1 ######################################## # Modifying the bjets and ljets lists ######################################## boosted_bjets = [] boosted_ljets = [] if n_excluded_bjets <= 1: if "subjet" in self.conf.general["verbosity"]: print "subjet replacing" # Add the subjets to the final output lists first for subjet in top_subjets: if subjet.btagFlag == 1.0: boosted_bjets.append( subjet ) if subjet.btagFlag == 0.0: boosted_ljets.append( subjet ) # Sort tl btagged jets by decreasing btag (to be sure, but should # already be done in previous analyzer) # Only resolved b-jets reco_btagged_jets = sorted( reco_btagged_jets, key=lambda x: -x.btag ) # Add up to 4 reco btagged jets to the output lists for bjet in reco_btagged_jets: # Check if the b-jet is not excluded if not hasattr( bjet, 'matched_top_subjet' ): boosted_bjets.append( bjet ) # Stop adding after 4 b-jets if len(boosted_bjets) == 4: break event.PassedSubjetAnalyzer = True # If too many events are excluded, just run the default hypothesis else: if "subjet" in self.conf.general["verbosity"]: print "[SubjetAnalyzer] subjet has too many overlaps, using reco" boosted_bjets = reco_btagged_jets boosted_ljets = reco_ltagged_jets event.PassedSubjetAnalyzer = False ######################################## # Write to event ######################################## # Store output lists in event event.higgsCandidate = higgsCandidates all_tops_to_add = [] # Add top matched to leading fatjet OR dummy for top in all_tops: if top.fj_index == 0: all_tops_to_add.append(top) break if len(all_tops_to_add) == 0: all_tops_to_add.append(DummyTop()) # Add top matched to sub-leading fatjet OR dummy for top in all_tops: if top.fj_index == 1: all_tops_to_add.append( top) break if len(all_tops_to_add) == 1: all_tops_to_add.append(DummyTop()) event.topCandidatesSync = all_tops_to_add if len(tops)>0: event.topCandidate = [ top ] event.othertopCandidate = other_tops event.boosted_bjets = boosted_bjets event.boosted_ljets = boosted_ljets event.n_boosted_bjets = len( boosted_bjets ) event.n_boosted_ljets = len( boosted_ljets ) event.n_excluded_bjets = n_excluded_bjets event.n_excluded_ljets = n_excluded_ljets #pdb.set_trace() if "subjet" in self.conf.general["verbosity"]: print '[SubjetAnalyzer] Exiting SubjetAnalyzer! event.PassedSubjetAnalyzer = {0}'.format( event.PassedSubjetAnalyzer ) ######################################## # Matching to Gen top ########################################### event.n_matched_TTgentop = -1 event.matched_TTgentop_pt = -1 event.n_matched_TTgenb = -1 event.n_matched_TTgenW = -1 if self.cfg_comp.isMC and len(tops)>0: self.Do_GenTop_Matching(event) return event ######################################## # Quark Matching ######################################## # This section is only useful for truth-level comparison, and can be turned # off if this is not needed. # Do_Quark_Matching( event ) sets number of matches with quarks as branches # in the event, but these branches do not have to be filled (they will be # automatically set to -1 in the final output root file). if self.cfg_comp.isMC: self.Do_Quark_Matching( event )