Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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 
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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]
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    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),
        )
Ejemplo n.º 12
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
Ejemplo n.º 13
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
Ejemplo n.º 14
0
    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
Ejemplo n.º 15
0
    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
Ejemplo n.º 16
0
    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
Ejemplo n.º 17
0
    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
Ejemplo n.º 18
0
    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
Ejemplo n.º 19
0
    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),
        )
Ejemplo n.º 20
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 )
Ejemplo n.º 21
0
    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
Ejemplo n.º 22
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 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 )