def fillHistos(chain, histosThisGroupPerSource, isData, lepton, group, selection, verbose=False):
    "expect histos[sel][source][var][loose,tight]"
    normFactor = 3.2 if group=='heavyflavor' else 1.0 # bb/cc hand-waving normalization factor, see notes 2014-04-17
    nLepFilled = 0
    num_processed_entries = 0
    for event in chain :
        num_processed_entries += 1
        pars = event.pars
        weight, evtN, runN = pars.weight, pars.eventNumber, pars.runNumber
        weight = weight*normFactor
        l0, l1 = kin.addTlv(event.l0), kin.addTlv(event.l1)
        met = kin.addTlv(event.met)
        jets = [kin.addTlv(j) for j in event.jets]
        dphi_ll_vBetaT, mdeltar = kin.computeRazor(l0.p4, l1.p4, met.p4)
        sourceReal = 3 # see FakeLeptonSources.h
        l0IsFake = l0.source!=sourceReal and not isData
        l1IsFake = l0.source!=sourceReal and not isData
        atLeastOneIsFake = l0IsFake or l1IsFake
        if not atLeastOneIsFake : continue
        is_same_sign = int((l0.charge * l1.charge)>0)
        is_opp_sign = not is_same_sign
        l0_pt, l1_pt = l0.p4.Pt(), l1.p4.Pt()
        dphi_l0_met = abs(l0.p4.DeltaPhi(met.p4))
        dphi_l1_met = abs(l1.p4.DeltaPhi(met.p4))
        dphi_l0_l1 = abs(l0.p4.DeltaPhi(l1.p4))
        pass_selection = (is_opp_sign and l0_pt>45.0 and l1_pt>12.0)
                          # and
                          # dphi_l0_l1>2.3 and dphi_l1_met<0.7 and dphi_l0_met>2.5
                          # and (l0_pt-l1_pt)>7.0)
        if not pass_selection : continue

        def fillHistosBySource(lep):
            isTight = lep.isTight
            source = lep.source
            leptonSource = enum2source(lep)
            isReal = source==sourceReal and not isData
            isFake = not isReal and not isData
            sourceIsKnown = not isData
            isRightLep = lep.isMu and lepton=='mu' or lep.isEl and lepton=='el'
            def fill():
                pt, eta, mt = lep.p4.Pt(), abs(lep.p4.Eta()), computeMt(lep.p4, met.p4)
                pt, eta, mt = shiftWithinRange(pt, eta, mt) # avoid loosing entries due to over/underflow
                histosThisGroupPerSource[selection][leptonSource]['mt'     ]['loose'].Fill(mt,      weight)
                histosThisGroupPerSource[selection][leptonSource]['pt'     ]['loose'].Fill(pt,      weight)
                histosThisGroupPerSource[selection][leptonSource]['eta'    ]['loose'].Fill(eta,     weight)
                histosThisGroupPerSource[selection][leptonSource]['mdeltar']['loose'].Fill(mdeltar, weight)
                histosThisGroupPerSource[selection][leptonSource]['pt_eta' ]['loose'].Fill(pt, eta, weight)
            filled = False
            # if isRightLep and sourceIsKnown and isFake: # DG-2014-08-08: pt cut still needed? and lep.p4.Pt()>20.0:
            if isRightLep and sourceIsKnown and isFake: # and mdeltar>20.0: # DG-2014-10-17: try razor mod sel
                fill()
                filled = True
            return filled
        if fillHistosBySource(l0) : nLepFilled += 1
        if fillHistosBySource(l1) : nLepFilled += 1
    if verbose : print "filled histos for %d leptons"%nLepFilled
    return num_processed_entries
def fillHistosAndCount(histos, files, lls, njs, testRun=False) :
    "Fill the histograms, and provide a dict of event counters[sample][sel] for the summary"
    treename = 'SusySel'
    counts = dict()
    for sample, filename in files.iteritems() :
        countsSample = collections.defaultdict(float)
        histosSample = histos[sample]
        file = r.TFile.Open(filename)
        tree = file.Get(treename)
        nEvents = tree.GetEntries()
        nEventsToProcess = nEvents if not testRun else nEvents/10
        print "processing %s (%d entries %s) %s"%(sample, nEventsToProcess, ", 10% test" if testRun else "", datetime.datetime.now())
        for iEvent, event in enumerate(tree) :
            if iEvent > nEventsToProcess : break
            l0, l1, met, pars = addTlv(event.l0), addTlv(event.l1), addTlv(event.met), event.pars
            jets, lepts = [addTlv(j) for j in event.jets], [addTlv(l) for l in event.lepts]
            ll = getDilepType(l0, l1)
            nJets = len(jets)
            nj = 'eq1j' if nJets==1 else 'ge2j'
            assert nJets>0,"messed something up in the selection upstream"
            if ll not in lls or nj not in njs : continue
            pt0 = l0.p4.Pt()
            pt1 = l1.p4.Pt()
            j0  = jets[0]
            mll  = (l0.p4 + l1.p4).M()
            mtllmet = computeMt(l0.p4 + l1.p4, met.p4)
            ht      = computeHt(met.p4, [l0.p4, l1.p4]+[j.p4 for j in jets])
            metrel  = computeMetRel(met.p4, [l0.p4, l1.p4]+[j.p4 for j in jets])
            mtl0    = computeMt(l0.p4, met.p4)
            mtl1    = computeMt(l1.p4, met.p4)
            mtmin   = min([mtl0, mtl1])
            mtmax   = max([mtl0, mtl1])
            mlj     = computeMlj(l0.p4, l1.p4, j0.p4)
            dphill  = abs(phi_mpi_pi(l0.p4.DeltaPhi(l1.p4)))
            detall  = fabs(l0.p4.Eta() - l1.p4.Eta())
            l3Veto  =  not thirdLepZcandidateIsInWindow(l0, l1, lepts)
            mljj = None
            if nJets >1 :
                j0, j1 = jets[0], jets[1]
                mt2j   = computeMt2j(l0.p4, l1.p4, j0.p4, j1.p4, met.p4)
                mljj   = computeMljj(l0.p4, l1.p4, j0.p4, j1.p4)
                dphijj = fabs(phi_mpi_pi(j0.p4.DeltaPhi(j1.p4)))
                detajj = fabs(j0.p4.Eta() - j1.p4.Eta())
            if passSelection(pt0, pt1, mll, mtllmet, ht, metrel, l3Veto,
                             detall, mtmax, mlj, mljj,
                             ll, nj) :
                llnj = llnjKey(ll, nj)
                weight = pars.weight
                varHistos = histosSample[llnj]
                varValues = dict([(v, eval(v)) for v in variablesToPlot()])
                fillVarHistos(varHistos, varValues, weight, nj)
                countsSample[llnj] += weight
        file.Close()
        file.Delete()
        counts[sample] = countsSample
    return counts
def createOutTree(filenames, dilepChan, nJetChan, tag='', overwrite=False) :
    assert dilepChan in ['ee','mm','em']
    assert nJetChan in ['eq1j', 'ge2j']
    outFilenames = dict()
    for sample, filename in filenames.iteritems() :
        outFilename = '/tmp/'+sample+'_'+dilepChan+'_'+nJetChan+'.root'
        if os.path.exists(outFilename) and not overwrite :
            outFilenames[sample] = outFilename
            continue
        outFile = r.TFile.Open(outFilename, 'recreate')
        outTree = r.TTree("training","Training tree")
        outTree.Branch('vars', vars, '/F:'.join(leafNames))
        outTree.SetDirectory(outFile)
        file = r.TFile.Open(filename)
        tree = file.Get(treename)
        print "processing %s %s %s (%d entries)"%(sample, dilepChan, nJetChan, tree.GetEntries())
        for iEvent, event in enumerate(tree) :
            resetVars(vars)
            l0 = addTlv(event.l0)
            l1 = addTlv(event.l1)
            met = addTlv(event.met)
            jets = [addTlv(j) for j in event.jets]
            lepts = [addTlv(l) for l in event.lepts]
            pars = event.pars
            dilepType = getDilepType(event.l0, event.l1)
            nJets = len(jets)
            if dilepType != dilepChan : continue
            if nJets<1 or (nJets>1 and nJetChan=='eq1j') : continue
            if thirdLepZcandidateIsInWindow(l0, l1, lepts, 20.0) : continue
            mt0, mt1 = computeMt(l0.p4, met.p4), computeMt(l1.p4, met.p4)
            vars.pt0 = l0.p4.Pt()
            vars.pt1 = l1.p4.Pt()
            vars.mll = (l0.p4+l1.p4).M()
            vars.mtmin = min([mt0, mt1])
            vars.mtmax = max([mt0, mt1])
            vars.mtllmet = computeMt(l0.p4 + l1.p4, met.p4)
            vars.ht = computeHt(met.p4, [l0.p4, l1.p4]+[j.p4 for j in jets])
            vars.metrel = computeMetRel(met.p4, [l0.p4, l1.p4]+[j.p4 for j in jets])
            vars.dphill = fabs(phi_mpi_pi(l0.p4.DeltaPhi(l1.p4)))
            vars.detall = fabs(l0.p4.Eta() - l1.p4.Eta())
            if nJets >1 :
                j0, j1 = jets[0], jets[1]
                vars.mt2j = computeMt2j(l0.p4, l1.p4, j0.p4, j1.p4, met.p4)
                vars.mljj = computeMljj(l0.p4, l1.p4, j0.p4, j1.p4)
                vars.dphijj = fabs(phi_mpi_pi(j0.p4.DeltaPhi(j1.p4)))
                vars.detajj = fabs(j0.p4.Eta() - j1.p4.Eta())
            outTree.Fill()
        print "filled ",outTree.GetEntries()," entries"
        outFile.Write()
        outFile.Close()
        outFilenames[sample] = outFile.GetName()
    return outFilenames
Exemplo n.º 4
0
def count_and_fill(chain, sample='', syst='', verbose=False, debug=False, blinded=True,
                   onthefly_tight_def=None, tightight=False, quicktest=False,
                   cached_cut=None, noncached_cuts=[]):
    """
    count and fill for one sample (or group), one syst.
    """
    sysGroup = systUtils.Group(sample).setSyst(syst)
    is_mc = systUtils.Group(sample).isMc
    is_data = systUtils.Group(sample).isData
    is_qflip_sample = dataset.DatasetGroup(sample).is_qflip
    assert bool(cached_cut) != bool(noncached_cuts),"must choose either cached selection or non-cached selections: {}, {}".format(cached_cut, noncached_cuts)
    cuts = [cached_cut] if cached_cut else noncached_cuts
    if noncached_cuts:
        chain.preselect(None)
    selections = [c.GetName() for c in cuts]
    counters = book_counters(selections)
    histos = book_histograms(sample_name=sample, variables=variables_to_fill(),
                             systematics=[syst], selections=selections
                             )[syst]
    if is_qflip_sample : # for qflip, only fill ss histos
        selections = [s for s in selections if s.endswith('_ss')]
    weight_expr = 'event.pars.weight'
    weight_expr = sysGroup.weightLeafname
    qflip_expr = 'event.pars.qflipWeight'
    print 'weight_expr: ',weight_expr
    print 'selections: ','\n'.join(["%d) %s : %s"%(i, cut.GetName(), cut.GetTitle()) for i, cut in enumerate(cuts)])
    start_time = time.clock()
    num_total_entries = chain.GetEntries()
    num_processed_entries = 0
    fields_to_print = ['l0_pt', 'l1_pt', 'l0_eta', 'l1_eta',
                       'met_pt',
                       'm_ll', 'pt_ll', 'dpt_l0_l1',
                       'dphi_l0_met', 'dphi_l1_met', 'dphi_l0_l1',
                       'mt0', 'mt1',
                       'n_soft_jets',
                       'eta_csj0', 'phi_csj0', 'eta_csj1', 'phi_csj1']
    if debug : print ",".join(fields_to_print)
    for iEntry, event in enumerate(chain):
        if quicktest and 100*iEntry > num_total_entries: break
        run_num = event.pars.runNumber
        evt_num = event.pars.eventNumber
        l0 = addTlv(event.l0)
        l1 = addTlv(event.l1)
        met = addTlv(event.met)
        l0_is_el, l0_is_mu = l0.isEl, l0.isMu
        l1_is_el, l1_is_mu = l1.isEl, l1.isMu
        l0_is_t = onthefly_tight_def(l0) if onthefly_tight_def else l0.isTight
        l1_is_t = onthefly_tight_def(l1) if onthefly_tight_def else l1.isTight
        is_emu = int(l0_is_el and l1_is_mu)
        is_mue = int(l0_is_mu and l1_is_el)
        is_mumu = int(l0_is_mu and l1_is_mu)
        is_ee = int(l0_is_el and l1_is_el)
        is_same_sign = int((l0.charge * l1.charge)>0)
        is_opp_sign  = not is_same_sign
        is_qflippable = is_opp_sign and (l0_is_el or l1_is_el) and is_mc
        weight = eval(weight_expr)
        qflip_prob = eval(qflip_expr)
        # print "event : same sign {0}, opp_sign {1}, qflippable {2}, qflip_prob {3}".format(is_same_sign, is_opp_sign, is_qflippable, eval(qflip_expr))
        l0_pt, l1_pt = l0.p4.Pt(), l1.p4.Pt()
        d_pt0_pt1 = l0_pt - l1_pt
        l0_eta, l1_eta = l0.p4.Eta(), l1.p4.Eta()
        l0_phi, l1_phi = l0.p4.Phi(), l1.p4.Phi()
        met_pt = met.p4.Pt()
        m_ll = (l0.p4 + l1.p4).M()
        pt_ll = (l0.p4 + l1.p4).Pt()
        dphi_l0_met = abs(l0.p4.DeltaPhi(met.p4))
        dphi_l1_met = abs(l1.p4.DeltaPhi(met.p4))
        dphi_l0_l1 = abs(l0.p4.DeltaPhi(l1.p4))
        dpt_l0_l1 = l0.p4.Pt()-l1.p4.Pt()
        m_coll = computeCollinearMassLepTau(l0.p4, l1.p4, met.p4)
        mt0, mt1 = computeMt(l0.p4, met.p4), computeMt(l1.p4, met.p4)
        dphillbeta, mdr = computeRazor(l0.p4, l1.p4, met.p4)
        def jet_pt2(j) : return j.px*j.px+j.py*j.py
        cl_jets   = [addTlv(j) for j in event.jets if jet_pt2(j)>30.*30.]
        n_cl_jets = len(cl_jets)
        n_b_jets  = event.pars.numBjets
        n_f_jets  = event.pars.numFjets
        n_bf_jets = n_b_jets + n_f_jets
        n_jets = n_cl_jets + n_b_jets + n_f_jets
        # n_jets = event.pars.numFjets + event.pars.numBjets
        soft_jets = [addTlv(j) for j in event.jets if jet_pt2(j)<30.**2] # todo: merge with cl_jets loop
        n_soft_jets = len(soft_jets)
        csj0 = first(sorted(soft_jets, key=lambda j : j.p4.DeltaR(l0.p4)))
        csj1 = first(sorted(soft_jets, key=lambda j : j.p4.DeltaR(l1.p4)))
        eta_csj0 = csj0.p4.Eta() if csj0 else -5.0
        phi_csj0 = csj0.p4.Phi() if csj0 else -5.0
        eta_csj1 = csj1.p4.Eta() if csj1 else -5.0
        phi_csj1 = csj1.p4.Phi() if csj1 else -5.0
        drl0csj  = csj0.p4.DeltaR(l0.p4) if csj0 else None
        drl1csj  = csj1.p4.DeltaR(l1.p4) if csj1 else None
        m_jj     = (cl_jets[0].p4 + cl_jets[1].p4).M() if n_cl_jets>1 else None
        deta_jj  = abs(cl_jets[0].p4.Eta() - cl_jets[1].p4.Eta()) if n_cl_jets>1 else None
        pass_sels = {}
        if tightight and not (l0_is_t and l1_is_t) : continue

        for cut in cuts:
            sel = cut.GetName()
            sel_expr = cut.GetTitle()
            pass_sel = eval(sel_expr)# and (l0_pt>60.0 and dphi_l1_met<0.7)
            pass_sels[sel] = pass_sel
            is_ss_sel = sel.endswith('_ss')
            as_qflip = is_qflippable and (is_opp_sign and is_ss_sel)
            if is_qflip_sample and not as_qflip : pass_sel = False
            if not is_qflip_sample and as_qflip : pass_sel = False
            if not pass_sel : continue
            if pass_sel and not cached_cut : chain.add_entry_to_list(cut, iEntry)
            # <isElectron 1> <isElectron 2> <isTight 1> <isTight 2> <pt 1> <pt 2> <eta 1> <eta 2>
            lltype = "{0}{1}".format('e' if l0_is_el else 'mu', 'e' if l1_is_el else 'mu')
            qqtype = "{0}{1}".format('T' if l0_is_t else 'L', 'T' if l1_is_t else 'L')
            if debug : print ','.join([str(eval(_)) for _ in fields_to_print])
            def fmt(b) : return '1' if b else '0'
            # --- begin dbg
            # print "event: {0:12s} {1} {2} {3} {4} {5} {6} {7} {8}".format(lltype+' '+qqtype, #+' '+sel,
            #                                                               fmt(l0_is_el), fmt(l1_is_el),
            #                                                               fmt(l0_is_t), fmt(l1_is_t),
            #                                                               l0_pt, l1_pt,
            #                                                               l0.p4.Eta(), l1.p4.Eta())
            # print "event: {0:12s} {1} {2} {3:.2f} {4:.2f}".format(lltype+' '+qqtype+' '+sel,
            #                                                       run_num, evt_num,
            #                                                       l0_pt, l1_pt)
            # --- end dbg
            fill_weight = (weight * qflip_prob) if as_qflip else weight
            h = histos[sel]
            h['onebin'   ].Fill(1.0, fill_weight)
            h['njets'    ].Fill(n_jets, fill_weight)
            h['pt0'      ].Fill(l0_pt, fill_weight)
            h['pt1'      ].Fill(l1_pt, fill_weight)
            h['d_pt0_pt1'].Fill(d_pt0_pt1, fill_weight)
            h['eta0'     ].Fill(l0_eta, fill_weight)
            h['eta1'     ].Fill(l1_eta, fill_weight)
            h['phi0'     ].Fill(l0_phi, fill_weight)
            h['phi1'     ].Fill(l1_phi, fill_weight)
            h['mll'      ].Fill(m_ll, fill_weight)
            h['ptll'     ].Fill(pt_ll, fill_weight)
            h['met'      ].Fill(met_pt, fill_weight)
            h['dphil0met'].Fill(dphi_l0_met, fill_weight)
            h['dphil1met'].Fill(dphi_l1_met, fill_weight)
            h['nsj'          ].Fill(n_soft_jets,   fill_weight)
            h['pt0_vs_pt1'      ].Fill(l1_pt, l0_pt,       fill_weight)
            h['met_vs_pt1'      ].Fill(l1_pt, met.p4.Pt(), fill_weight)
            h['dphil0l1_vs_pt1' ].Fill(l1_pt, dphi_l0_l1,  fill_weight)
            h['dphil0met_vs_pt1'].Fill(l1_pt, dphi_l0_met, fill_weight)
            h['dphil1met_vs_pt1'].Fill(l1_pt, dphi_l1_met, fill_weight)
            if n_soft_jets:
                h['drl0csj'].Fill(drl0csj, fill_weight)
                h['drl1csj'].Fill(drl1csj, fill_weight)
            if n_jets==2 and n_cl_jets==2: # fixme: f jets are not saved, but we need them for vbf
                h['m_jj'   ].Fill(m_jj,    fill_weight)
                h['deta_jj'].Fill(deta_jj, fill_weight)
            if is_data and (blinded and 100.0<m_coll and m_coll<150.0) : pass
            else :
                h['mcoll'].Fill(m_coll, fill_weight)
                h['mcollcoarse'].Fill(m_coll, fill_weight)
                h['mcoll_vs_pt1'].Fill(l1_pt, m_coll, fill_weight)
            counters[sel] += (fill_weight)
        # print ('e' if l0_is_el else 'm'),('e' if l1_is_el else 'm'),' : ',
        # print ' is_opp_sign: ',is_opp_sign,
        # print ' is_qflippable: ',is_qflippable,
        # print pass_sels
        num_processed_entries += 1
    end_time = time.clock()
    delta_time = end_time - start_time
    if verbose:
        print ("processed {0:d} entries ".format(num_processed_entries)
               +"in "+("{0:d} min ".format(int(delta_time/60)) if delta_time>60 else
                       "{0:.1f} s ".format(delta_time))
               +"({0:.1f} kHz)".format((num_processed_entries/delta_time) if delta_time else 1.0e9)
               )
    if verbose:
        for v in ['onebin']: #, 'pt0', 'pt1']:
            for sel in selections:
                h = histos[sel][v]
                print "{0}: integral {1}, entries {2}".format(h.GetName(), h.Integral(), h.GetEntries())
    return counters, histos
Exemplo n.º 5
0
def count_and_fill(chain,
                   opts,
                   group=dataset.DatasetGroup('foo'),
                   cached_cut=None,
                   noncached_cuts=[]):
    """
    count and fill for one sample (or group)
    """
    is_data = group.is_data
    is_mc = not is_data
    is_qflip_sample = group.is_qflip
    assert bool(cached_cut) != bool(
        noncached_cuts
    ), "must choose either cached selection or non-cached selections: {}, {}".format(
        cached_cut, noncached_cuts)
    cuts = [cached_cut] if cached_cut else noncached_cuts
    if noncached_cuts:
        chain.preselect(None)
    selections = [c.GetName() for c in cuts]
    counters = dict((sel, 0) for sel in selections)
    quicktest = opts.quick_test
    tightight = opts.tight_tight
    verbose = opts.verbose

    histos = book_histograms(sample_name=group.name,
                             variables=variables_to_fill(),
                             selections=selections,
                             sources=leptonSources)
    weight_expr = 'event.pars.weight'
    start_time = time.clock()
    num_total_entries = chain.GetEntries()
    num_processed_entries = 0
    for iEntry, event in enumerate(chain):
        if quicktest and 100 * iEntry > num_total_entries: break
        if not event.l0.isTight: continue  # in the sel string
        if tightight and not event.l1.isTight: continue
        run_num = event.pars.runNumber
        evt_num = event.pars.eventNumber
        l0 = addTlv(event.l0)
        l1 = addTlv(event.l1)
        met = addTlv(event.met)
        l0_is_el, l0_is_mu = l0.isEl, l0.isMu
        l1_is_el, l1_is_mu = l1.isEl, l1.isMu
        is_emu = int(l0_is_el and l1_is_mu)
        is_mue = int(l0_is_mu and l1_is_el)
        is_mumu = int(l0_is_mu and l1_is_mu)
        is_ee = int(l0_is_el and l1_is_el)
        is_same_sign = int((l0.charge * l1.charge) > 0)
        is_opp_sign = not is_same_sign
        is_qflippable = is_opp_sign and (l0_is_el or l1_is_el) and is_mc
        weight = eval(weight_expr)
        l0_pt, l1_pt = l0.p4.Pt(), l1.p4.Pt()
        d_pt0_pt1 = l0_pt - l1_pt
        l0_eta, l1_eta = abs(l0.p4.Eta()), abs(l1.p4.Eta())
        dphi_l0_met = abs(l0.p4.DeltaPhi(met.p4))
        dphi_l1_met = abs(l1.p4.DeltaPhi(met.p4))
        dphi_l0_l1 = abs(l0.p4.DeltaPhi(l1.p4))
        dpt_l0_l1 = l0.p4.Pt() - l1.p4.Pt()
        # l0_source = None if is_data else enum2source(l0)
        # l1_source = None if is_data else enum2source(l1)
        l0_source = enum2source(l0)
        l1_source = enum2source(l1)

        def jet_pt2(j):
            return j.px * j.px + j.py * j.py

        n_cl_jets = sum(1 for j in event.jets if jet_pt2(j) > 30. * 30.)
        n_jets = n_cl_jets + event.pars.numFjets + event.pars.numBjets
        pass_sels = {}
        for cut in cuts:
            sel = cut.GetName()
            sel_expr = cut.GetTitle()
            pass_sel = eval(sel_expr)
            pass_sels[sel] = pass_sel
            if not pass_sel: continue
            if pass_sel and not cached_cut:
                chain.add_entry_to_list(cut, iEntry)
            fill_weight = (weight)
            histos[sel]['onebin'][l0_source].Fill(1.0, fill_weight)
            histos[sel]['pt0'][l0_source].Fill(l0_pt, fill_weight)
            histos[sel]['pt1'][l1_source].Fill(l1_pt, fill_weight)
            histos[sel]['eta0'][l0_source].Fill(l0_eta, fill_weight)
            histos[sel]['eta1'][l1_source].Fill(l1_eta, fill_weight)
            histos[sel]['pt_eta'][l0_source].Fill(l0_pt, l0_eta, fill_weight)
            histos[sel]['pt_eta'][l1_source].Fill(l1_pt, l1_eta, fill_weight)
        num_processed_entries += 1
    end_time = time.clock()
    delta_time = end_time - start_time
    if verbose:
        print(
            "processed {0:d} entries ".format(num_processed_entries) + "in " +
            ("{0:d} min ".format(int(delta_time / 60))
             if delta_time > 60 else "{0:.1f} s ".format(delta_time)) +
            "({0:.1f} kHz)".format((num_processed_entries /
                                    delta_time) if delta_time else 1.0e9))
    if verbose:
        for sel in selections:
            tot_integral = sum(
                h.Integral()
                for source, h in histos[sel]['onebin'].iteritems())
            tot_entries = sum(
                h.GetEntries()
                for source, h in histos[sel]['onebin'].iteritems())
            print "{0}: integral {1}, entries {2}".format(
                sel + '_onebin', tot_integral, tot_entries)
    return counters, histos
Exemplo n.º 6
0
def count_and_fill(chain,
                   sample='',
                   syst='',
                   verbose=False,
                   debug=False,
                   blinded=True,
                   onthefly_tight_def=None,
                   tightight=False,
                   quicktest=False,
                   cached_cut=None,
                   noncached_cuts=[]):
    """
    count and fill for one sample (or group), one syst.
    """
    sysGroup = systUtils.Group(sample).setSyst(syst)
    is_mc = systUtils.Group(sample).isMc
    is_data = systUtils.Group(sample).isData
    is_qflip_sample = dataset.DatasetGroup(sample).is_qflip
    assert bool(cached_cut) != bool(
        noncached_cuts
    ), "must choose either cached selection or non-cached selections: {}, {}".format(
        cached_cut, noncached_cuts)
    cuts = [cached_cut] if cached_cut else noncached_cuts
    if noncached_cuts:
        chain.preselect(None)
    selections = [c.GetName() for c in cuts]
    counters = book_counters(selections)
    histos = book_histograms(sample_name=sample,
                             variables=variables_to_fill(),
                             systematics=[syst],
                             selections=selections)[syst]
    if is_qflip_sample:  # for qflip, only fill ss histos
        selections = [s for s in selections if s.endswith('_ss')]
    weight_expr = 'event.pars.weight'
    weight_expr = sysGroup.weightLeafname
    qflip_expr = 'event.pars.qflipWeight'
    print 'weight_expr: ', weight_expr
    print 'selections: ', '\n'.join([
        "%d) %s : %s" % (i, cut.GetName(), cut.GetTitle())
        for i, cut in enumerate(cuts)
    ])
    start_time = time.clock()
    num_total_entries = chain.GetEntries()
    num_processed_entries = 0
    fields_to_print = [
        'l0_pt', 'l1_pt', 'l0_eta', 'l1_eta', 'met_pt', 'm_ll', 'pt_ll',
        'dpt_l0_l1', 'dphi_l0_met', 'dphi_l1_met', 'dphi_l0_l1', 'mt0', 'mt1',
        'n_soft_jets', 'eta_csj0', 'phi_csj0', 'eta_csj1', 'phi_csj1'
    ]
    if debug: print ",".join(fields_to_print)
    for iEntry, event in enumerate(chain):
        if quicktest and 100 * iEntry > num_total_entries: break
        run_num = event.pars.runNumber
        evt_num = event.pars.eventNumber
        l0 = addTlv(event.l0)
        l1 = addTlv(event.l1)
        met = addTlv(event.met)
        l0_is_el, l0_is_mu = l0.isEl, l0.isMu
        l1_is_el, l1_is_mu = l1.isEl, l1.isMu
        l0_is_t = onthefly_tight_def(l0) if onthefly_tight_def else l0.isTight
        l1_is_t = onthefly_tight_def(l1) if onthefly_tight_def else l1.isTight
        is_emu = int(l0_is_el and l1_is_mu)
        is_mue = int(l0_is_mu and l1_is_el)
        is_mumu = int(l0_is_mu and l1_is_mu)
        is_ee = int(l0_is_el and l1_is_el)
        is_same_sign = int((l0.charge * l1.charge) > 0)
        is_opp_sign = not is_same_sign
        is_qflippable = is_opp_sign and (l0_is_el or l1_is_el) and is_mc
        weight = eval(weight_expr)
        qflip_prob = eval(qflip_expr)
        # print "event : same sign {0}, opp_sign {1}, qflippable {2}, qflip_prob {3}".format(is_same_sign, is_opp_sign, is_qflippable, eval(qflip_expr))
        l0_pt, l1_pt = l0.p4.Pt(), l1.p4.Pt()
        d_pt0_pt1 = l0_pt - l1_pt
        l0_eta, l1_eta = l0.p4.Eta(), l1.p4.Eta()
        l0_phi, l1_phi = l0.p4.Phi(), l1.p4.Phi()
        met_pt = met.p4.Pt()
        m_ll = (l0.p4 + l1.p4).M()
        pt_ll = (l0.p4 + l1.p4).Pt()
        dphi_l0_met = abs(l0.p4.DeltaPhi(met.p4))
        dphi_l1_met = abs(l1.p4.DeltaPhi(met.p4))
        dphi_l0_l1 = abs(l0.p4.DeltaPhi(l1.p4))
        dpt_l0_l1 = l0.p4.Pt() - l1.p4.Pt()
        m_coll = computeCollinearMassLepTau(l0.p4, l1.p4, met.p4)
        mt0, mt1 = computeMt(l0.p4, met.p4), computeMt(l1.p4, met.p4)
        dphillbeta, mdr = computeRazor(l0.p4, l1.p4, met.p4)

        def jet_pt2(j):
            return j.px * j.px + j.py * j.py

        cl_jets = [addTlv(j) for j in event.jets if jet_pt2(j) > 30. * 30.]
        n_cl_jets = len(cl_jets)
        n_b_jets = event.pars.numBjets
        n_f_jets = event.pars.numFjets
        n_bf_jets = n_b_jets + n_f_jets
        n_jets = n_cl_jets + n_b_jets + n_f_jets
        # n_jets = event.pars.numFjets + event.pars.numBjets
        soft_jets = [addTlv(j) for j in event.jets
                     if jet_pt2(j) < 30.**2]  # todo: merge with cl_jets loop
        n_soft_jets = len(soft_jets)
        csj0 = first(sorted(soft_jets, key=lambda j: j.p4.DeltaR(l0.p4)))
        csj1 = first(sorted(soft_jets, key=lambda j: j.p4.DeltaR(l1.p4)))
        eta_csj0 = csj0.p4.Eta() if csj0 else -5.0
        phi_csj0 = csj0.p4.Phi() if csj0 else -5.0
        eta_csj1 = csj1.p4.Eta() if csj1 else -5.0
        phi_csj1 = csj1.p4.Phi() if csj1 else -5.0
        drl0csj = csj0.p4.DeltaR(l0.p4) if csj0 else None
        drl1csj = csj1.p4.DeltaR(l1.p4) if csj1 else None
        m_jj = (cl_jets[0].p4 + cl_jets[1].p4).M() if n_cl_jets > 1 else None
        deta_jj = abs(cl_jets[0].p4.Eta() -
                      cl_jets[1].p4.Eta()) if n_cl_jets > 1 else None
        pass_sels = {}
        if tightight and not (l0_is_t and l1_is_t): continue

        for cut in cuts:
            sel = cut.GetName()
            sel_expr = cut.GetTitle()
            pass_sel = eval(sel_expr)  # and (l0_pt>60.0 and dphi_l1_met<0.7)
            pass_sels[sel] = pass_sel
            is_ss_sel = sel.endswith('_ss')
            as_qflip = is_qflippable and (is_opp_sign and is_ss_sel)
            if is_qflip_sample and not as_qflip: pass_sel = False
            if not is_qflip_sample and as_qflip: pass_sel = False
            if not pass_sel: continue
            if pass_sel and not cached_cut:
                chain.add_entry_to_list(cut, iEntry)
            # <isElectron 1> <isElectron 2> <isTight 1> <isTight 2> <pt 1> <pt 2> <eta 1> <eta 2>
            lltype = "{0}{1}".format('e' if l0_is_el else 'mu',
                                     'e' if l1_is_el else 'mu')
            qqtype = "{0}{1}".format('T' if l0_is_t else 'L',
                                     'T' if l1_is_t else 'L')
            if debug: print ','.join([str(eval(_)) for _ in fields_to_print])

            def fmt(b):
                return '1' if b else '0'

            # --- begin dbg
            # print "event: {0:12s} {1} {2} {3} {4} {5} {6} {7} {8}".format(lltype+' '+qqtype, #+' '+sel,
            #                                                               fmt(l0_is_el), fmt(l1_is_el),
            #                                                               fmt(l0_is_t), fmt(l1_is_t),
            #                                                               l0_pt, l1_pt,
            #                                                               l0.p4.Eta(), l1.p4.Eta())
            # print "event: {0:12s} {1} {2} {3:.2f} {4:.2f}".format(lltype+' '+qqtype+' '+sel,
            #                                                       run_num, evt_num,
            #                                                       l0_pt, l1_pt)
            # --- end dbg
            fill_weight = (weight * qflip_prob) if as_qflip else weight
            h = histos[sel]
            h['onebin'].Fill(1.0, fill_weight)
            h['njets'].Fill(n_jets, fill_weight)
            h['pt0'].Fill(l0_pt, fill_weight)
            h['pt1'].Fill(l1_pt, fill_weight)
            h['d_pt0_pt1'].Fill(d_pt0_pt1, fill_weight)
            h['eta0'].Fill(l0_eta, fill_weight)
            h['eta1'].Fill(l1_eta, fill_weight)
            h['phi0'].Fill(l0_phi, fill_weight)
            h['phi1'].Fill(l1_phi, fill_weight)
            h['mll'].Fill(m_ll, fill_weight)
            h['ptll'].Fill(pt_ll, fill_weight)
            h['met'].Fill(met_pt, fill_weight)
            h['dphil0met'].Fill(dphi_l0_met, fill_weight)
            h['dphil1met'].Fill(dphi_l1_met, fill_weight)
            h['nsj'].Fill(n_soft_jets, fill_weight)
            h['pt0_vs_pt1'].Fill(l1_pt, l0_pt, fill_weight)
            h['met_vs_pt1'].Fill(l1_pt, met.p4.Pt(), fill_weight)
            h['dphil0l1_vs_pt1'].Fill(l1_pt, dphi_l0_l1, fill_weight)
            h['dphil0met_vs_pt1'].Fill(l1_pt, dphi_l0_met, fill_weight)
            h['dphil1met_vs_pt1'].Fill(l1_pt, dphi_l1_met, fill_weight)
            if n_soft_jets:
                h['drl0csj'].Fill(drl0csj, fill_weight)
                h['drl1csj'].Fill(drl1csj, fill_weight)
            if n_jets == 2 and n_cl_jets == 2:  # fixme: f jets are not saved, but we need them for vbf
                h['m_jj'].Fill(m_jj, fill_weight)
                h['deta_jj'].Fill(deta_jj, fill_weight)
            if is_data and (blinded and 100.0 < m_coll and m_coll < 150.0):
                pass
            else:
                h['mcoll'].Fill(m_coll, fill_weight)
                h['mcollcoarse'].Fill(m_coll, fill_weight)
                h['mcoll_vs_pt1'].Fill(l1_pt, m_coll, fill_weight)
            counters[sel] += (fill_weight)
        # print ('e' if l0_is_el else 'm'),('e' if l1_is_el else 'm'),' : ',
        # print ' is_opp_sign: ',is_opp_sign,
        # print ' is_qflippable: ',is_qflippable,
        # print pass_sels
        num_processed_entries += 1
    end_time = time.clock()
    delta_time = end_time - start_time
    if verbose:
        print(
            "processed {0:d} entries ".format(num_processed_entries) + "in " +
            ("{0:d} min ".format(int(delta_time / 60))
             if delta_time > 60 else "{0:.1f} s ".format(delta_time)) +
            "({0:.1f} kHz)".format((num_processed_entries /
                                    delta_time) if delta_time else 1.0e9))
    if verbose:
        for v in ['onebin']:  #, 'pt0', 'pt1']:
            for sel in selections:
                h = histos[sel][v]
                print "{0}: integral {1}, entries {2}".format(
                    h.GetName(), h.Integral(), h.GetEntries())
    return counters, histos
def main():
    test_first_1k_events = True
    print_events_as_txt = False # needed to evaluate the matrix on stdin
    base_dir = '/gdata/atlas/gerbaudo/hlfv/take0/SusyntHlfv/run/out/matrix_prediction'
    dir1 = base_dir+'/Jul_26/'
    dir2 = base_dir+'/May_20/'
    tree_name = 'hlfv_tuple'
    chain1 = r.TChain(tree_name)
    for f in sorted(glob.glob(dir1+'/*.root*')) : chain1.Add(f)
    chain2 = r.TChain(tree_name)
    for f in sorted(glob.glob(dir2+'/*.root*')) : chain2.Add(f)
    entries1 =chain1.GetEntries()
    entries2 =chain2.GetEntries()
    print 'chain1 ',entries1
    print 'chain2 ',entries2
    # assert entries1==entries2,"the two chains must have the same entries (matching events), {0}!={1}".format(entries1, entries2)
    min_weight, max_weight = 1.0e6, -1.0e6
    h_w1_vs_w2   = r.TH2F('h_w2_vs_w1',   'fake weight: Jul_26 vs. May_20; w Jul_26; w May_20', 100, -0.75, +0.75, 100, -0.75, +0.75)
    h_w1_vs_w2_s = r.TH2F('h_w2_vs_w1_s', 'fake weight: Jul_26 vs. May_20; w Jul_26; w May_20', 100, -0.75, +0.75, 100, -0.75, +0.75)
    chain1.SetAlias("weight1", "weight")
    chain2.SetAlias("weight2", "weight")
    print 'chain1 ',dir1
    chain1.Scan("runNumber:eventNumber:weight", "", "", 10)
    print 'chain2 ',dir2
    chain2.Scan("runNumber:eventNumber:weight", "", "", 10) 
    chain1.AddFriend(chain2, "May_20")
    chain1.Draw("weight1:May_20.weight2 >> "+h_w1_vs_w2_s.GetName())
    out_file = r.TFile.Open('fake_weight_comparison.root', 'recreate')
    out_file.cd()
    out_tree = r.TTree('fake_weight_tree',
                       'tree to compare fake weights: '
                       +"w1 from {0}".format(dir1)
                       +"w2 from {0}".format(dir2))
    weights = array.array('d', 2*[0.0])
    pts = array.array('d', 2*[0.0])
    isEmu = array.array( 'i', 1*[0] )
    isSameSign = array.array( 'i', 1*[0] )
    out_tree.Branch('weights', weights, 'weights[%d]/D'%len(weights))
    out_tree.Branch('pts', pts, 'pts[%d]/D'%len(pts))
    out_tree.Branch('isEmu', isEmu, 'isEmu[%d]/I'%len(isEmu))
    out_tree.Branch('isSameSign', isSameSign, 'isSameSign[%d]/I'%len(isSameSign))

    for iEntry in xrange(entries1):
        if test_first_1k_events and iEntry>1000 : break
        chain1.GetEntry(iEntry)
        chain2.GetEntry(iEntry)
        r1, e1, w1 = chain1.pars.runNumber, chain1.pars.eventNumber, chain1.pars.weight
        r2, e2, w2 = chain2.pars.runNumber, chain2.pars.eventNumber, chain2.pars.weight
        if r1!=r2 or e1!=e2:
            print "1) run {0}, event {1}, weight {2}".format(r1, e1, w1)
            print "2) run {0}, event {1}, weight {2}".format(r2, e2, w2)
        assert r1==r2,"different run number {0}!={1}".format(r1, r2)
        assert e1==e2,"different evt number {0}!={1}".format(e1, e2)
        min_weight = min_weight if min_weight<min([w1, w2]) else min([w1, w2])
        max_weight = max_weight if max_weight>max([w1, w2]) else max([w1, w2])
        h_w1_vs_w2.Fill(w1, w2)
        weights[0], weights[1] = w1, w2
        l0, l1 = chain1.l0, chain1.l1
        l0 = addTlv(l0)
        l1 = addTlv(l1)
        pts[0], pts[1] = l0.p4.Pt(), l1.p4.Pt()
        isEl0, isMu0 = l0.isEl, l0.isMu
        isEl1, isMu1 = l1.isEl, l1.isMu
        isEmu[0] = int((isEl0 and isMu1) or (isMu1 and isMu0))
        isSameSign[0] = int((l0.charge * l1.charge)>0)
        values = {'run':r1, 'event':e1,
                  'weight':w1,
                  'isEl1': 1 if isEl0 else 0,
                  'isEl2': 1 if isEl1 else 0,
                  'isTight1': 1 if l0.isTight else 0,
                  'isTight2': 1 if l1.isTight else 0,
                  'pt1': pts[0], 'pt2': pts[1],
                  'eta1': l0.p4.Eta(), 'eta2': l1.p4.Eta()
                  }
        if print_events_as_txt and isEmu[0]:
            print "{run} {event} {weight} {isEl1} {isEl2} {isTight1} {isTight2} {pt1} {pt2} {eta1} {eta2}".format(**values)

        out_tree.Fill()
    print "weight: min {0}, max {1}".format(min_weight, max_weight)
    print "output entries: ",out_tree.GetEntries()
    out_tree.Write()
    out_file.Close()
    
    c = r.TCanvas('c_w1_vs_w2_draw','fake weight: Jul_26 vs. May_20')
    c.cd()
    h_w1_vs_w2.Draw('scat')
    c.SaveAs(h_w1_vs_w2.GetName()+'.png')
    c.SaveAs(h_w1_vs_w2.GetName()+'.root')
    
    c = r.TCanvas('c_w1_vs_w2_draw','fake weight: Jul_26 vs. May_20')
    c.cd()
    c.Clear()
    h_w1_vs_w2_s.Draw('scat')
    c.SaveAs(h_w1_vs_w2_s.GetName()+'.png')
    c.SaveAs(h_w1_vs_w2_s.GetName()+'.root')
def fillHistos(chain, histosThisGroup, histosPerSource, histosThisGroupPerSource,
               lepton, group, cut, cut_is_cached, onthefly_tight_def=None, verbose=False):
    nLoose, nTight = 0, 0
    totWeightLoose, totWeightTight = 0.0, 0.0
    normFactor = 1.0 if group=='heavyflavor' else 1.0 # bb/cc hand-waving normalization factor, see notes 2014-04-17
    addTlv, computeMt = kin.addTlv, kin.computeMt
    region = cut.GetName()
    sel = cut.GetName()
    sel_expr = cut.GetTitle()
    print group
    isData = group.name=='data'
    isHflf = region=='hflf'
    print 'TODO: check isHflf'
    print 'TODO: check hasTrigmatch (already in ntuple creation?)'
    isConversion = region=='conv'
    if group=='heavyflavor':
        if lepton=='el' and not isConversion : normFactor = 1.6
        if lepton=='mu' :                      normFactor = 0.87
    num_processed_entries = 0
    sourceReal = r.hlfv.LeptonTruthType.Prompt
    for iEvent, event in enumerate(chain) :
        num_processed_entries += 1
        pars = event.pars
        weight, evtN, runN = pars.weight, pars.eventNumber, pars.runNumber
        hasTrigmatch = True # pars.has2ltrigmatch==1
        weight = weight*normFactor
        tag, probe, met = addTlv(event.l0), addTlv(event.l1), addTlv(event.met)
        if not (tag.isMu and probe.isMu) : continue
        isSameSign = tag.charge*probe.charge > 0.
        isRightProbe = probe.isEl if lepton=='el' else probe.isMu if lepton=='mu' else False
        if not isRightProbe and lepton=='el':
            tag, probe = probe, tag # if we are  picking emu instead of mue
            isRightProbe = probe.isEl if lepton=='el' else False

        tagIsTight = onthefly_tight_def(tag) if onthefly_tight_def else tag.isTight
        isTight = onthefly_tight_def(probe) if onthefly_tight_def else probe.isTight # todo: rename to probeIsTight
        probeSource = probe.source
        isReal = probeSource==sourceReal and not isData
        isFake = not isReal and not isData
        jets = event.jets
        jets = [addTlv(j) for j in jets] # only if needed
        def isBjet(j, mv1_80=0.3511) : return j.mv1 > mv1_80 # see SusyDefs.h
        hasBjets = any(isBjet(j) for j in jets) # compute only if necessary
        hasFjets = any(abs(j.p4.Eta())>2.4 and j.p4.Pt()>30. for j in jets)
        hasCLjets = any(abs(j.p4.Eta())<2.4 and j.p4.Pt()>30 and not isBjet(j) for j in jets)
        hasJ30jets = any(j.p4.Pt()>30. for j in jets)
        hasJets = hasBjets or hasFjets or hasCLjets
        tag4m, probe4m, met4m = r.TLorentzVector(), r.TLorentzVector(), r.TLorentzVector()
        tag4m.SetPxPyPzE(tag.px, tag.py, tag.pz, tag.E)
        probe4m.SetPxPyPzE(probe.px, probe.py, probe.pz, probe.E)
        met4m.SetPxPyPzE(met.px, met.py, met.pz, met.E)
        pt = probe4m.Pt()
        eta = abs(probe4m.Eta())
        mt0 = computeMt(tag4m, met4m)
        mt1 = computeMt(probe4m, met4m)
        pt0 = tag4m.Pt()
        pt1 = probe4m.Pt()
        passTrigBias =  True
        if   isHflf       : passTrigBias = pt0>20.0 and pt1>20.0
        elif isConversion : passTrigBias = pt1>20.0

        is_mumu = tag.isMu and probe.isMu
        is_same_sign = isSameSign
        is_opp_sign = not is_same_sign
        tag_is_mu = tag.isMu
        tag_is_tight = tagIsTight
        probe_is_tight = isTight
        probe_is_mu = probe.isMu
        probe_is_el = probe.isEl
        l0_is_el, l0_is_mu = event.l0.isEl, event.l0.isMu
        l1_is_el, l1_is_mu = event.l1.isEl, event.l1.isMu
        is_ee   = l0_is_el and l1_is_el
        is_emu  = l0_is_el and l1_is_mu
        is_mue  = l0_is_mu and l1_is_el
        is_mumu = l0_is_mu and l1_is_mu
        m_ll = (tag4m+probe4m).M()
        pass_sel = eval(sel_expr)
        if pass_sel and not cut_is_cached : chain.add_entry_to_list(cut, iEvent)
        # if tag.isMu and isRightProbe and isSameSign : # test 1 : no jet req
        # if tag.isMu and tag.isTight and isRightProbe and isSameSign : # test 2 : reproduce counts from hlfv
        def fillHistosBySource(probe):
            leptonSource = enum2source(probe)
            # if leptonSource=='Unknown':
            #     print 'unknown lep from ',group.name,' pt ',pt,' eta ',eta,' file ',chain.GetCurrentFile().GetName()
            def fillPerSource(tightOrLoose):
                histosPerSource         ['mt1' ][leptonSource][tightOrLoose].Fill(mt1, weight)
                histosPerSource         ['pt1' ][leptonSource][tightOrLoose].Fill(pt,  weight)
                histosPerSource         ['eta1'][leptonSource][tightOrLoose].Fill(eta, weight)
                histosThisGroupPerSource['mt1' ][leptonSource][tightOrLoose].Fill(mt1, weight)
                histosThisGroupPerSource['pt1' ][leptonSource][tightOrLoose].Fill(pt,  weight)
                histosThisGroupPerSource['eta1'][leptonSource][tightOrLoose].Fill(eta, weight)
                histosThisGroupPerSource['pt1_eta1'][leptonSource][tightOrLoose].Fill(pt, eta, weight)
            fillPerSource('loose')
            if isTight :
                fillPerSource('tight')
        def fill(lepType=''):
            histosThisGroup['mt0' ][lepType].Fill(mt0, weight)
            histosThisGroup['pt0' ][lepType].Fill(pt0, weight)
            histosThisGroup['mt1' ][lepType].Fill(mt1, weight)
            histosThisGroup['pt1' ][lepType].Fill(pt, weight)
            histosThisGroup['eta1'][lepType].Fill(eta, weight)
            histosThisGroup['pt1_eta1'][lepType].Fill(pt, eta, weight)

        sourceIsKnown = not isData
        nLoose         += 1
        totWeightLoose += weight
        if isTight:
            nTight         += 1
            totWeightTight += weight

        fill(lepType='loose')
        if sourceIsKnown:
            fillHistosBySource(probe)
        if isTight            : fill(lepType='tight')
        if isReal             : fill(lepType='real_loose')
        if isFake             : fill(lepType='fake_loose')
        if isReal and isTight : fill(lepType='real_tight')
        if isFake and isTight : fill(lepType='fake_tight')
    if verbose:
        counterNames = ['nLoose', 'nTight', 'totWeightLoose', 'totWeightTight']
        print ', '.join(["%s : %.1f"%(c, eval(c)) for c in counterNames])
    return num_processed_entries
def main():
    test_first_1k_events = True
    print_events_as_txt = False  # needed to evaluate the matrix on stdin
    base_dir = '/gdata/atlas/gerbaudo/hlfv/take0/SusyntHlfv/run/out/matrix_prediction'
    dir1 = base_dir + '/Jul_26/'
    dir2 = base_dir + '/May_20/'
    tree_name = 'hlfv_tuple'
    chain1 = r.TChain(tree_name)
    for f in sorted(glob.glob(dir1 + '/*.root*')):
        chain1.Add(f)
    chain2 = r.TChain(tree_name)
    for f in sorted(glob.glob(dir2 + '/*.root*')):
        chain2.Add(f)
    entries1 = chain1.GetEntries()
    entries2 = chain2.GetEntries()
    print 'chain1 ', entries1
    print 'chain2 ', entries2
    # assert entries1==entries2,"the two chains must have the same entries (matching events), {0}!={1}".format(entries1, entries2)
    min_weight, max_weight = 1.0e6, -1.0e6
    h_w1_vs_w2 = r.TH2F('h_w2_vs_w1',
                        'fake weight: Jul_26 vs. May_20; w Jul_26; w May_20',
                        100, -0.75, +0.75, 100, -0.75, +0.75)
    h_w1_vs_w2_s = r.TH2F(
        'h_w2_vs_w1_s', 'fake weight: Jul_26 vs. May_20; w Jul_26; w May_20',
        100, -0.75, +0.75, 100, -0.75, +0.75)
    chain1.SetAlias("weight1", "weight")
    chain2.SetAlias("weight2", "weight")
    print 'chain1 ', dir1
    chain1.Scan("runNumber:eventNumber:weight", "", "", 10)
    print 'chain2 ', dir2
    chain2.Scan("runNumber:eventNumber:weight", "", "", 10)
    chain1.AddFriend(chain2, "May_20")
    chain1.Draw("weight1:May_20.weight2 >> " + h_w1_vs_w2_s.GetName())
    out_file = r.TFile.Open('fake_weight_comparison.root', 'recreate')
    out_file.cd()
    out_tree = r.TTree(
        'fake_weight_tree', 'tree to compare fake weights: ' +
        "w1 from {0}".format(dir1) + "w2 from {0}".format(dir2))
    weights = array.array('d', 2 * [0.0])
    pts = array.array('d', 2 * [0.0])
    isEmu = array.array('i', 1 * [0])
    isSameSign = array.array('i', 1 * [0])
    out_tree.Branch('weights', weights, 'weights[%d]/D' % len(weights))
    out_tree.Branch('pts', pts, 'pts[%d]/D' % len(pts))
    out_tree.Branch('isEmu', isEmu, 'isEmu[%d]/I' % len(isEmu))
    out_tree.Branch('isSameSign', isSameSign,
                    'isSameSign[%d]/I' % len(isSameSign))

    for iEntry in xrange(entries1):
        if test_first_1k_events and iEntry > 1000: break
        chain1.GetEntry(iEntry)
        chain2.GetEntry(iEntry)
        r1, e1, w1 = chain1.pars.runNumber, chain1.pars.eventNumber, chain1.pars.weight
        r2, e2, w2 = chain2.pars.runNumber, chain2.pars.eventNumber, chain2.pars.weight
        if r1 != r2 or e1 != e2:
            print "1) run {0}, event {1}, weight {2}".format(r1, e1, w1)
            print "2) run {0}, event {1}, weight {2}".format(r2, e2, w2)
        assert r1 == r2, "different run number {0}!={1}".format(r1, r2)
        assert e1 == e2, "different evt number {0}!={1}".format(e1, e2)
        min_weight = min_weight if min_weight < min([w1, w2]) else min(
            [w1, w2])
        max_weight = max_weight if max_weight > max([w1, w2]) else max(
            [w1, w2])
        h_w1_vs_w2.Fill(w1, w2)
        weights[0], weights[1] = w1, w2
        l0, l1 = chain1.l0, chain1.l1
        l0 = addTlv(l0)
        l1 = addTlv(l1)
        pts[0], pts[1] = l0.p4.Pt(), l1.p4.Pt()
        isEl0, isMu0 = l0.isEl, l0.isMu
        isEl1, isMu1 = l1.isEl, l1.isMu
        isEmu[0] = int((isEl0 and isMu1) or (isMu1 and isMu0))
        isSameSign[0] = int((l0.charge * l1.charge) > 0)
        values = {
            'run': r1,
            'event': e1,
            'weight': w1,
            'isEl1': 1 if isEl0 else 0,
            'isEl2': 1 if isEl1 else 0,
            'isTight1': 1 if l0.isTight else 0,
            'isTight2': 1 if l1.isTight else 0,
            'pt1': pts[0],
            'pt2': pts[1],
            'eta1': l0.p4.Eta(),
            'eta2': l1.p4.Eta()
        }
        if print_events_as_txt and isEmu[0]:
            print "{run} {event} {weight} {isEl1} {isEl2} {isTight1} {isTight2} {pt1} {pt2} {eta1} {eta2}".format(
                **values)

        out_tree.Fill()
    print "weight: min {0}, max {1}".format(min_weight, max_weight)
    print "output entries: ", out_tree.GetEntries()
    out_tree.Write()
    out_file.Close()

    c = r.TCanvas('c_w1_vs_w2_draw', 'fake weight: Jul_26 vs. May_20')
    c.cd()
    h_w1_vs_w2.Draw('scat')
    c.SaveAs(h_w1_vs_w2.GetName() + '.png')
    c.SaveAs(h_w1_vs_w2.GetName() + '.root')

    c = r.TCanvas('c_w1_vs_w2_draw', 'fake weight: Jul_26 vs. May_20')
    c.cd()
    c.Clear()
    h_w1_vs_w2_s.Draw('scat')
    c.SaveAs(h_w1_vs_w2_s.GetName() + '.png')
    c.SaveAs(h_w1_vs_w2_s.GetName() + '.root')
def fillHistos(chain, histosThisGroup, histosPerSource, isData, lepton, group, verbose=False):
    nLoose, nTight = 0, 0
    totWeightLoose, totWeightTight = 0.0, 0.0
    for event in chain :
        pars = event.pars
        weight, evtN, runN = pars.weight, pars.eventNumber, pars.runNumber
        weight = weight
        probe = kin.addTlv(event.l1)
        met = kin.addTlv(event.met)
        isRightLep = probe.isEl if lepton=='el' else probe.isMu if lepton=='mu' else False
        if not isRightLep : continue
        # isTight = probe.isTight # this is the same as isTight_wh
        isTight        = fakeu.isTight_wh    (probe)
        isTight_std    = fakeu.isTight_std   (probe)
        isTight_minden = fakeu.isTight_minden(probe)
        isTight_tight  = fakeu.isTight_tight (probe)
        if (isData and isTight != probe.isTight):
            print "isTight_wh %s isTight %s run %d event %d" % (isTight, probe.isTight, evtN, runN)
            print "(RunNumber==%d && EventNumber==%d)"%(runN, evtN)
            pt = probe.p4.Pt()
            relEtCone = probe.etConeCorr/min([pt, 60.0])
            relPtCone = probe.ptConeCorr/min([pt, 60.0])
            print "pt %.2f etCone %.2f relEt %.2f, ptCone %.2f relPt %.2f"%(pt, probe.etConeCorr, relEtCone, probe.ptConeCorr, relPtCone)
            fakeu.elecIsIsolatedVerbose(probe, fakeu.denominator_wh(probe))
        pt = probe.p4.Pt()
        eta = abs(probe.p4.Eta())
        d0Sig, z0Sin = probe.d0Signif, probe.z0SinTheta
        etCone, ptCone = probe.etCone, probe.ptCone
        etConeCorr, ptConeCorr = probe.etConeCorr, probe.ptConeCorr
        relDenomStd, relDenomMod = fakeu.denominator_std(probe), fakeu.denominator_wh(probe)
        relEtConeStd, relPtConeStd = etConeCorr*relDenomStd, ptConeCorr*relDenomStd
        relEtConeMod, relPtConeMod = etConeCorr*relDenomMod, ptConeCorr*relDenomMod
        def shiftWithinRange(v, maxV=0.40, epsilon=1.0e-3) : return maxV*(1.0-epsilon) if v>=maxV else v
        for vv in [relEtConeStd, relPtConeStd, relEtConeMod, relPtConeMod] : vv = shiftWithinRange(vv)
        relEtConeStd = shiftWithinRange(relEtConeStd)
        relPtConeStd = shiftWithinRange(relPtConeStd)
        relEtConeMod = shiftWithinRange(relEtConeMod)
        relPtConeMod = shiftWithinRange(relPtConeMod)
        selection = True
        source = None if isData else enum2source(probe)
        if selection:
            def incrementCounts(counts, weightedCounts):
                counts +=1
                weightedCounts += weight
            def fillPerGroup(tightOrLoose):
                histosThisGroup['pt'          ][tightOrLoose].Fill(pt, weight)
                histosThisGroup['eta'         ][tightOrLoose].Fill(eta, weight)
                histosThisGroup['d0sig'       ][tightOrLoose].Fill(d0Sig, weight)
                histosThisGroup['z0SinTheta'  ][tightOrLoose].Fill(z0Sin, weight)
                histosThisGroup['etCone'      ][tightOrLoose].Fill(etCone, weight)
                histosThisGroup['ptCone'      ][tightOrLoose].Fill(ptCone, weight)
                histosThisGroup['etConeCorr'  ][tightOrLoose].Fill(etConeCorr, weight)
                histosThisGroup['ptConeCorr'  ][tightOrLoose].Fill(ptConeCorr, weight)
                histosThisGroup['relEtConeStd'][tightOrLoose].Fill(relEtConeStd, weight)
                histosThisGroup['relPtConeStd'][tightOrLoose].Fill(relPtConeStd, weight)
                histosThisGroup['relEtConeMod'][tightOrLoose].Fill(relEtConeMod, weight)
                histosThisGroup['relPtConeMod'][tightOrLoose].Fill(relPtConeMod, weight)
                if source:
                    histosThisSource = histosPerSource[source]
                    histosThisSource['pt'          ][tightOrLoose].Fill(pt, weight)
                    histosThisSource['eta'         ][tightOrLoose].Fill(eta, weight)
                    histosThisSource['d0sig'       ][tightOrLoose].Fill(d0Sig, weight)
                    histosThisSource['z0SinTheta'  ][tightOrLoose].Fill(z0Sin, weight)
                    histosThisSource['etCone'      ][tightOrLoose].Fill(etCone, weight)
                    histosThisSource['ptCone'      ][tightOrLoose].Fill(ptCone, weight)
                    histosThisSource['etConeCorr'  ][tightOrLoose].Fill(etConeCorr, weight)
                    histosThisSource['ptConeCorr'  ][tightOrLoose].Fill(ptConeCorr, weight)
                    histosThisSource['relEtConeStd'][tightOrLoose].Fill(relEtConeStd, weight)
                    histosThisSource['relPtConeStd'][tightOrLoose].Fill(relPtConeStd, weight)
                    histosThisSource['relEtConeMod'][tightOrLoose].Fill(relEtConeMod, weight)
                    histosThisSource['relPtConeMod'][tightOrLoose].Fill(relPtConeMod, weight)

            incrementCounts(nLoose, totWeightLoose)
            fillPerGroup('loose')
            if isTight:
                incrementCounts(nTight, totWeightTight)
                fillPerGroup('tight')
            if isTight_std:
                fillPerGroup('tight_std')
            if isTight_minden:
                fillPerGroup('tight_minden')
            if isTight_tight:
                fillPerGroup('tight_tight')
    if verbose:
        counterNames = ['nLoose', 'nTight', 'totWeightLoose', 'totWeightTight']
        print ', '.join(["%s : %.1f"%(c, eval(c)) for c in counterNames])
Exemplo n.º 11
0
def count_and_fill(chain,  opts, group=dataset.DatasetGroup('foo'),
                   cached_cut=None, noncached_cuts=[]):
    """
    count and fill for one sample (or group)
    """
    is_data = group.is_data
    is_mc = not is_data
    is_qflip_sample = group.is_qflip
    assert bool(cached_cut) != bool(noncached_cuts),"must choose either cached selection or non-cached selections: {}, {}".format(cached_cut, noncached_cuts)
    cuts = [cached_cut] if cached_cut else noncached_cuts
    if noncached_cuts:
        chain.preselect(None)
    selections = [c.GetName() for c in cuts]
    counters = dict((sel, 0) for sel in selections)
    quicktest = opts.quick_test
    tightight = opts.tight_tight
    verbose = opts.verbose

    histos = book_histograms(sample_name=group.name, variables=variables_to_fill(),
                             selections=selections, sources=leptonSources)
    weight_expr = 'event.pars.weight'
    start_time = time.clock()
    num_total_entries = chain.GetEntries()
    num_processed_entries = 0
    for iEntry, event in enumerate(chain):
        if quicktest and 100*iEntry > num_total_entries: break
        if not event.l0.isTight: continue # in the sel string
        if tightight and not event.l1.isTight: continue
        run_num = event.pars.runNumber
        evt_num = event.pars.eventNumber
        l0 = addTlv(event.l0)
        l1 = addTlv(event.l1)
        met = addTlv(event.met)
        l0_is_el, l0_is_mu = l0.isEl, l0.isMu
        l1_is_el, l1_is_mu = l1.isEl, l1.isMu
        is_emu = int(l0_is_el and l1_is_mu)
        is_mue = int(l0_is_mu and l1_is_el)
        is_mumu = int(l0_is_mu and l1_is_mu)
        is_ee = int(l0_is_el and l1_is_el)
        is_same_sign = int((l0.charge * l1.charge)>0)
        is_opp_sign  = not is_same_sign
        is_qflippable = is_opp_sign and (l0_is_el or l1_is_el) and is_mc
        weight = eval(weight_expr)
        l0_pt, l1_pt = l0.p4.Pt(), l1.p4.Pt()
        d_pt0_pt1 = l0_pt - l1_pt
        l0_eta, l1_eta = abs(l0.p4.Eta()), abs(l1.p4.Eta())
        dphi_l0_met = abs(l0.p4.DeltaPhi(met.p4))
        dphi_l1_met = abs(l1.p4.DeltaPhi(met.p4))
        dphi_l0_l1 = abs(l0.p4.DeltaPhi(l1.p4))
        dpt_l0_l1 = l0.p4.Pt()-l1.p4.Pt()
        # l0_source = None if is_data else enum2source(l0)
        # l1_source = None if is_data else enum2source(l1)
        l0_source = enum2source(l0)
        l1_source = enum2source(l1)
        def jet_pt2(j) : return j.px*j.px+j.py*j.py
        n_cl_jets = sum(1 for j in event.jets if jet_pt2(j)>30.*30.)
        n_jets = n_cl_jets + event.pars.numFjets + event.pars.numBjets
        pass_sels = {}
        for cut in cuts:
            sel = cut.GetName()
            sel_expr = cut.GetTitle()
            pass_sel = eval(sel_expr)
            pass_sels[sel] = pass_sel
            if not pass_sel : continue
            if pass_sel and not cached_cut : chain.add_entry_to_list(cut, iEntry)
            fill_weight = (weight)
            histos[sel]['onebin'][l0_source].Fill(1.0, fill_weight)
            histos[sel]['pt0'   ][l0_source].Fill(l0_pt, fill_weight)
            histos[sel]['pt1'   ][l1_source].Fill(l1_pt, fill_weight)
            histos[sel]['eta0'  ][l0_source].Fill(l0_eta, fill_weight)
            histos[sel]['eta1'  ][l1_source].Fill(l1_eta, fill_weight)
            histos[sel]['pt_eta'][l0_source].Fill(l0_pt, l0_eta, fill_weight)
            histos[sel]['pt_eta'][l1_source].Fill(l1_pt, l1_eta, fill_weight)
        num_processed_entries += 1
    end_time = time.clock()
    delta_time = end_time - start_time
    if verbose:
        print ("processed {0:d} entries ".format(num_processed_entries)
               +"in "+("{0:d} min ".format(int(delta_time/60)) if delta_time>60 else
                       "{0:.1f} s ".format(delta_time))
               +"({0:.1f} kHz)".format((num_processed_entries/delta_time) if delta_time else 1.0e9)
               )
    if verbose:
        for sel in selections:
            tot_integral = sum(h.Integral() for source, h in histos[sel]['onebin'].iteritems())
            tot_entries = sum(h.GetEntries() for source, h in histos[sel]['onebin'].iteritems())
            print "{0}: integral {1}, entries {2}".format(sel+'_onebin', tot_integral, tot_entries)
    return counters, histos
def fillHistos() :
    filenames = getInputFiles()
    hs_nlep = dict()
    hs_nillep = dict()
    hs_npairs = dict()
    hs_masses = dict()
    hs_bestm = dict()
    hs_bestlpt = dict()
    hs_bestleta= dict()
    hs_bestdphi= dict()
    hs_bestdrj = dict()
    for sample, filename in filenames.iteritems() :
        file = r.TFile.Open(filename)
        tree = file.Get(treename)
        print "processing %s (%d entries)"%(sample, tree.GetEntries())
        iEvent = 0
        h_nlep   = r.TH1F('h_nlep_'+sample, '; N_{lep, low-p_{T}};entries/bin', 5, -0.5, 4.5)
        h_nillep = r.TH1F('h_nillep_'+sample,
                          'separated from signal leptons; N_{lep, iso-lep, low-p_{T}};entries/bin',
                          5, -0.5, 4.5)
        h_npairs  = r.TH1F('h_npairs_'+sample, '; N_{valid pairs}; entries/bin', 5, -0.5, 4.5)
        h_masses  = r.TH1F('h_masses_'+sample, '; m_{ll}, any valid pair [GeV]; entries/bin', 25, 0.0, 200.0)
        h_bestm   = r.TH1F('h_bestm_'+sample, '; m_{ll}, best pair [GeV]; entries/bin', 25, 0.0, 200.0)
        h_bestlpt = r.TH1F('h_bestlpt_'+sample, '; p_{T}, best soft lepton [GeV]; entries/bin', 25, 0.0, 200.0)
        h_bestleta= r.TH1F('h_bestleta_'+sample, '; #eta, best soft lepton; entries/bin', 25, -3.0, +3.0)
        h_bestdphi= r.TH1F('h_bestdphi'+sample, '; |#Delta#phi(l_{hard},l_{soft})|, best pair [rad]; entries/bin',
                           25, 0.0, +2.*math.pi)
        h_bestdrj = r.TH1F('h_bestdrj'+sample, '; min#DeltaR(l_{soft}), best soft lep; entries/bin',
                           20, 0.0, 2.0)
        for event in tree :
            l0 = addTlv(event.l0)
            l1 = addTlv(event.l1)
            met = addTlv(event.met)
            jets = [addTlv(j) for j in event.jets]
            lepts = [addTlv(l) for l in event.lepts]
            pars = event.pars
            weight, evtN, runN = pars.weight, pars.eventNumber, pars.runNumber
            h_nlep.Fill(float(len(lepts)), weight)
            if len(lepts) < 1 : continue
            lepts = filter(lambda l : lepIsSeparatedFromOther(l.p4, [l0.p4, l1.p4]), lepts)
            h_nillep.Fill(float(len(lepts)), weight)
            validPairs = [(lh, ls) for lh in [l0, l1] for ls in lepts if lepPairIsZcand(lh, ls)]
            h_npairs.Fill(float(len(validPairs)), weight)
            pairsSortedByBestM = sorted(validPairs, key=deltaMZ0)
            for i,(lh,ls) in enumerate(pairsSortedByBestM) :
                m = (lh.p4+ls.p4).M()
                h_masses.Fill(m, weight)
                if i==0 :
                    h_bestm.Fill(m, weight)
                    h_bestlpt.Fill(ls.p4.Pt(), weight)
                    h_bestleta.Fill(ls.p4.Eta(), weight)
                    h_bestdphi.Fill(abs(phi_mpi_pi(ls.p4.DeltaPhi(lh.p4))), weight)
                    if len(jets) :
                        minDrJ = sorted([ls.p4.DeltaR(j.p4) for j in jets])[0]
                        h_bestdrj.Fill(minDrJ, weight)
            if iEvent<10 : print "jets [%d], lepts[%d]"%(len(jets), len(lepts))
            iEvent += 1
        hs_nlep    [sample] = h_nlep
        hs_nillep  [sample] = h_nillep
        hs_npairs  [sample] = h_npairs
        hs_masses  [sample] = h_masses
        hs_bestm   [sample] = h_bestm
        hs_bestlpt [sample] = h_bestlpt
        hs_bestleta[sample] = h_bestleta
        hs_bestdphi[sample] = h_bestdphi
        hs_bestdrj [sample] = h_bestdrj
    return {'hs_nlep'    : hs_nlep,
            'hs_nillep'  : hs_nillep,
            'hs_npairs'  : hs_npairs,
            'hs_masses'  : hs_masses,
            'hs_bestm'   : hs_bestm,
            'hs_bestlpt' : hs_bestlpt,
            'hs_bestleta': hs_bestleta,
            'hs_bestdphi': hs_bestdphi,
            'hs_bestdrj' : hs_bestdrj
            }
def fillHistos(chain,
               histosThisGroup,
               histosPerSource,
               histosThisGroupPerSource,
               lepton,
               group,
               cut,
               cut_is_cached,
               onthefly_tight_def=None,
               verbose=False):
    nLoose, nTight = 0, 0
    totWeightLoose, totWeightTight = 0.0, 0.0
    normFactor = 1.0 if group == 'heavyflavor' else 1.0  # bb/cc hand-waving normalization factor, see notes 2014-04-17
    addTlv, computeMt = kin.addTlv, kin.computeMt
    region = cut.GetName()
    sel = cut.GetName()
    sel_expr = cut.GetTitle()
    print group
    isData = group.name == 'data'
    isHflf = region == 'hflf'
    print 'TODO: check isHflf'
    print 'TODO: check hasTrigmatch (already in ntuple creation?)'
    isConversion = region == 'conv'
    if group == 'heavyflavor':
        if lepton == 'el' and not isConversion: normFactor = 1.6
        if lepton == 'mu': normFactor = 0.87
    num_processed_entries = 0
    sourceReal = r.hlfv.LeptonTruthType.Prompt
    for iEvent, event in enumerate(chain):
        num_processed_entries += 1
        pars = event.pars
        weight, evtN, runN = pars.weight, pars.eventNumber, pars.runNumber
        hasTrigmatch = True  # pars.has2ltrigmatch==1
        weight = weight * normFactor
        tag, probe, met = addTlv(event.l0), addTlv(event.l1), addTlv(event.met)
        if not (tag.isMu and probe.isMu): continue
        isSameSign = tag.charge * probe.charge > 0.
        isRightProbe = probe.isEl if lepton == 'el' else probe.isMu if lepton == 'mu' else False
        if not isRightProbe and lepton == 'el':
            tag, probe = probe, tag  # if we are  picking emu instead of mue
            isRightProbe = probe.isEl if lepton == 'el' else False

        tagIsTight = onthefly_tight_def(
            tag) if onthefly_tight_def else tag.isTight
        isTight = onthefly_tight_def(
            probe
        ) if onthefly_tight_def else probe.isTight  # todo: rename to probeIsTight
        probeSource = probe.source
        isReal = probeSource == sourceReal and not isData
        isFake = not isReal and not isData
        jets = event.jets
        jets = [addTlv(j) for j in jets]  # only if needed

        def isBjet(j, mv1_80=0.3511):
            return j.mv1 > mv1_80  # see SusyDefs.h

        hasBjets = any(isBjet(j) for j in jets)  # compute only if necessary
        hasFjets = any(abs(j.p4.Eta()) > 2.4 and j.p4.Pt() > 30. for j in jets)
        hasCLjets = any(
            abs(j.p4.Eta()) < 2.4 and j.p4.Pt() > 30 and not isBjet(j)
            for j in jets)
        hasJ30jets = any(j.p4.Pt() > 30. for j in jets)
        hasJets = hasBjets or hasFjets or hasCLjets
        tag4m, probe4m, met4m = r.TLorentzVector(), r.TLorentzVector(
        ), r.TLorentzVector()
        tag4m.SetPxPyPzE(tag.px, tag.py, tag.pz, tag.E)
        probe4m.SetPxPyPzE(probe.px, probe.py, probe.pz, probe.E)
        met4m.SetPxPyPzE(met.px, met.py, met.pz, met.E)
        pt = probe4m.Pt()
        eta = abs(probe4m.Eta())
        mt0 = computeMt(tag4m, met4m)
        mt1 = computeMt(probe4m, met4m)
        pt0 = tag4m.Pt()
        pt1 = probe4m.Pt()
        passTrigBias = True
        if isHflf: passTrigBias = pt0 > 20.0 and pt1 > 20.0
        elif isConversion: passTrigBias = pt1 > 20.0

        is_mumu = tag.isMu and probe.isMu
        is_same_sign = isSameSign
        is_opp_sign = not is_same_sign
        tag_is_mu = tag.isMu
        tag_is_tight = tagIsTight
        probe_is_tight = isTight
        probe_is_mu = probe.isMu
        probe_is_el = probe.isEl
        l0_is_el, l0_is_mu = event.l0.isEl, event.l0.isMu
        l1_is_el, l1_is_mu = event.l1.isEl, event.l1.isMu
        is_ee = l0_is_el and l1_is_el
        is_emu = l0_is_el and l1_is_mu
        is_mue = l0_is_mu and l1_is_el
        is_mumu = l0_is_mu and l1_is_mu
        m_ll = (tag4m + probe4m).M()
        pass_sel = eval(sel_expr)
        if pass_sel and not cut_is_cached: chain.add_entry_to_list(cut, iEvent)

        # if tag.isMu and isRightProbe and isSameSign : # test 1 : no jet req
        # if tag.isMu and tag.isTight and isRightProbe and isSameSign : # test 2 : reproduce counts from hlfv
        def fillHistosBySource(probe):
            leptonSource = enum2source(probe)

            # if leptonSource=='Unknown':
            #     print 'unknown lep from ',group.name,' pt ',pt,' eta ',eta,' file ',chain.GetCurrentFile().GetName()
            def fillPerSource(tightOrLoose):
                histosPerSource['mt1'][leptonSource][tightOrLoose].Fill(
                    mt1, weight)
                histosPerSource['pt1'][leptonSource][tightOrLoose].Fill(
                    pt, weight)
                histosPerSource['eta1'][leptonSource][tightOrLoose].Fill(
                    eta, weight)
                histosThisGroupPerSource['mt1'][leptonSource][
                    tightOrLoose].Fill(mt1, weight)
                histosThisGroupPerSource['pt1'][leptonSource][
                    tightOrLoose].Fill(pt, weight)
                histosThisGroupPerSource['eta1'][leptonSource][
                    tightOrLoose].Fill(eta, weight)
                histosThisGroupPerSource['pt1_eta1'][leptonSource][
                    tightOrLoose].Fill(pt, eta, weight)

            fillPerSource('loose')
            if isTight:
                fillPerSource('tight')

        def fill(lepType=''):
            histosThisGroup['mt0'][lepType].Fill(mt0, weight)
            histosThisGroup['pt0'][lepType].Fill(pt0, weight)
            histosThisGroup['mt1'][lepType].Fill(mt1, weight)
            histosThisGroup['pt1'][lepType].Fill(pt, weight)
            histosThisGroup['eta1'][lepType].Fill(eta, weight)
            histosThisGroup['pt1_eta1'][lepType].Fill(pt, eta, weight)

        sourceIsKnown = not isData
        nLoose += 1
        totWeightLoose += weight
        if isTight:
            nTight += 1
            totWeightTight += weight

        fill(lepType='loose')
        if sourceIsKnown:
            fillHistosBySource(probe)
        if isTight: fill(lepType='tight')
        if isReal: fill(lepType='real_loose')
        if isFake: fill(lepType='fake_loose')
        if isReal and isTight: fill(lepType='real_tight')
        if isFake and isTight: fill(lepType='fake_tight')
    if verbose:
        counterNames = ['nLoose', 'nTight', 'totWeightLoose', 'totWeightTight']
        print ', '.join(["%s : %.1f" % (c, eval(c)) for c in counterNames])
    return num_processed_entries