Beispiel #1
0
def doCounters(opts, dsetMgr, moduleInfoString, myDir, luminosity,
               normFactors):
    def printSubCounterTable(eventCounter, subCounterName, cellFormat):
        # Check existence
        if subCounterName in eventCounter.getSubCounterNames():
            # Subcounter exists, go ahead and print it
            return eventCounter.getSubCounterTable(subCounterName).format(
                cellFormat)
        else:
            return "Subcounter '%s' does not exist (please note that for optimization runs subcounters are not saved)" % subCounterName

    eventCounter = counter.EventCounter(dsetMgr)
    eventCounter.normalizeMCToLuminosity(myLuminosity)
    print "============================================================"
    print "Main counter (MC normalized by collision data luminosity)"
    mainTable = eventCounter.getMainCounterTable()
    # No uncertainties
    cellFormat = counter.TableFormatText(cellFormat=counter.CellFormatText(
        valueOnly=True))
    myOutput = ""
    myOutput += mainTable.format(cellFormat) + "\n\n"
    myOutput += printSubCounterTable(eventCounter, "b-tagging",
                                     cellFormat) + "\n\n"
    myOutput += printSubCounterTable(eventCounter, "Jet selection",
                                     cellFormat) + "\n\n"
    myOutput += printSubCounterTable(eventCounter, "Jet main",
                                     cellFormat) + "\n\n"
    # Write the output to file
    f = open(os.path.join(myDir, "counterOutput.txt"), "w")
    f.write(myOutput)
    f.close()
    # Write the output to screen
    print myOutput
def printCounters(datasets):
    print "============================================================"
    print "Dataset info: "
    datasets.printInfo()

    eventCounter = counter.EventCounter(datasets)
    if True:
        selection = "Sum$(%s) >= 1" % muonKinematics
        eventCounter.getMainCounter().appendRow("Muon kinematics", treeDraw.clone(selection=selection))
        selection = "Sum$(%s && %s) >= 1" % (muonKinematics, muondB)
        eventCounter.getMainCounter().appendRow("Muon IP", treeDraw.clone(selection=selection))
        selection = "Sum$(%s && %s && %s) >= 1" % (muonKinematics, muondB, muonIsolation)
        eventCounter.getMainCounter().appendRow("Muon isolation", treeDraw.clone(selection=selection))
        selection = "Sum$(%s && %s && %s) == 1" % (muonKinematics, muondB, muonIsolation)
        print selection
        eventCounter.getMainCounter().appendRow("One selected muon", treeDraw.clone(selection=selection))
        selection += "&&" +muonVeto
        print selection
        eventCounter.getMainCounter().appendRow("Muon veto", treeDraw.clone(selection=selection))
        selection += "&&" +electronVeto
        print selection
        eventCounter.getMainCounter().appendRow("Electron veto", treeDraw.clone(selection=selection))
        selection += "&&" +jetSelection
        print selection
        eventCounter.getMainCounter().appendRow("Jet selection", treeDraw.clone(selection=selection))

    eventCounter.normalizeMCByLuminosity()

    table = eventCounter.getMainCounterTable()
    addSumColumn(table)

    cellFormat = counter.TableFormatText(counter.CellFormatText(valueFormat='%.3f'))
    print table.format(cellFormat)
def printCounters(datasets,
                  selectionName,
                  ntupleCache,
                  selectorName,
                  onlyDataset=None):
    global printed
    if not printed:
        print "============================================================"
        print "Dataset info: "
        datasets.printInfo()
        printed = True

    if not doWeighted:
        eventCounter = counter.EventCounter(datasets, counters=counters)
        counterPath = "counters/counter"
    else:
        eventCounter = counter.EventCounter(datasets)
        counterPath = "counters/weighted/counter"

    if onlyDataset != None:
        eventCounter.removeColumns(
            filter(lambda n: n != onlyDataset, datasets.getAllDatasetNames()))

    eventCounter.getMainCounter().appendRows(
        ntupleCache.histogram(counterPath, selectorName))

    if mergeMC:
        if mcOnly:
            eventCounter.normalizeMCToLuminosity(mcLuminosity)
        else:
            eventCounter.normalizeMCByLuminosity()

    table = eventCounter.getMainCounterTable()
    mcDatasets = filter(lambda n: n != "Data", table.getColumnNames())
    if len(mcDatasets) != 0:
        col = 1
        if mcOnly:
            col = 0
        table.insertColumn(
            col,
            counter.sumColumn(
                "MCSum", [table.getColumn(name=name) for name in mcDatasets]))

    cellFormat = counter.TableFormatText(
        counter.CellFormatText(valueFormat='%.3f'))
    #    cellFormat = counter.TableFormatText(counter.CellFormatTeX(valueFormat='%.1f'))
    output = table.format(cellFormat)

    print
    print "########################################"
    print "Selection", selectionName
    print output

    prefix = era + "_" + selectionName + "_counters"
    if not doWeighted:
        prefix += "_nonweighted"
    f = open(prefix + ".txt", "w")
    f.write(output)
    f.close()
def doCounters(datasets, ntupleCache):
    # Counters
    eventCounter = counter.EventCounter(datasets)
    mainCounter = eventCounter.getMainCounter();
    counters = "counters/counter"
    if dataEra != "":
        counters = "counters/weighted/counter"
    mainCounter.appendRows(ntupleCache.histogram(counters))

    format = counter.TableFormatText(counter.CellFormatText(valueFormat="%.0f"))

    table = mainCounter.getTable()
    print table.format(format)

    effFormat = counter.TableFormatText(counter.CellFormatText(valueFormat="%.2f", withPrecision=2))

    teffs = mainCounter.constructTEfficiencies(createTEfficiency)
    table = counter.efficiencyTableFromTEfficiencies(teffs, mainCounter.getColumnNames(), rowNames)
    table.multiply(100)
    print table.format(effFormat)
Beispiel #5
0
def doCounters(myDsetMgr, mySuffix, isSystematicVariation):
    eventCounter = counter.EventCounter(myDsetMgr)

    # append row from the tree to the main counter
#    eventCounter.getMainCounter().appendRow("MET > 70", treeDraw.clone(selection="met_p4.Et() > 70"))

    ewkDatasets = [
        "WJets", "TTJets",
        "DYJetsToLL", "SingleTop", "Diboson"
        ]
    if myDsetMgr.hasDataset("W1Jets"):
        ewkDatasets.extend(["W1Jets", "W2Jets", "W3Jets", "W4Jets"])

    if mcOnly:
        eventCounter.normalizeMCToLuminosity(mcOnlyLumi)
    else:
        eventCounter.normalizeMCByLuminosity()
    print "============================================================"
    print mySuffix
    print "============================================================"
    out = open(os.path.join(mySuffix, "counters.txt"), "w")
    def printAndSave(line):
        print line
        out.write(line)
        out.write("\n")

    printAndSave("Main counter (MC normalized by collision data luminosity)")
    mainTable = eventCounter.getMainCounterTable()
    mainTable.insertColumn(2, counter.sumColumn("EWKMCsum", [mainTable.getColumn(name=name) for name in ewkDatasets]))
    # Default
#    cellFormat = counter.TableFormatText()
    # No uncertainties
    cellFormat = counter.TableFormatText(cellFormat=counter.CellFormatText(valueOnly=False))
    printAndSave(mainTable.format(cellFormat))



    if not isSystematicVariation:
#        printAndSave(eventCounter.getSubCounterTable("tauIDTauSelection").format())
        printAndSave(eventCounter.getSubCounterTable("TauIDPassedEvt::TauSelection_HPS").format(cellFormat))
        printAndSave(eventCounter.getSubCounterTable("TauIDPassedJets::TauSelection_HPS").format(cellFormat))
        printAndSave(eventCounter.getSubCounterTable("b-tagging").format(cellFormat))
        printAndSave(eventCounter.getSubCounterTable("Jet selection").format(cellFormat))
        printAndSave(eventCounter.getSubCounterTable("Jet main").format(cellFormat))
        printAndSave(eventCounter.getSubCounterTable("VetoTauSelection").format(cellFormat))
        printAndSave(eventCounter.getSubCounterTable("MuonSelection").format(cellFormat))
        printAndSave(eventCounter.getSubCounterTable("MCinfo for selected events").format(cellFormat))
        printAndSave(eventCounter.getSubCounterTable("ElectronSelection").format(cellFormat))
#        printAndSave(eventCounter.getSubCounterTable("top").format(cellFormat))

    out.close()
Beispiel #6
0
def doCounters(datasets):
    eventCounter = counter.EventCounter(datasets)

    eventCounter.normalizeMCByLuminosity()
    #    eventCounter.normalizeMCToLuminosity(73)
    print "============================================================"
    print "Main counter (MC normalized by collision data luminosity)"
    mainTable = eventCounter.getMainCounterTable()
    # No uncertainties
    cellFormat = counter.TableFormatText(cellFormat=counter.CellFormatText(
        valueOnly=True))
    print mainTable.format(cellFormat)

    print eventCounter.getSubCounterTable("b-tagging").format(cellFormat)
    print eventCounter.getSubCounterTable("Jet selection").format(cellFormat)
    print eventCounter.getSubCounterTable("Jet main").format(cellFormat)
def doCounters(myDsetMgr, mySuffix):
    eventCounter = counter.EventCounter(myDsetMgr)

    # append row from the tree to the main counter
    #    eventCounter.getMainCounter().appendRow("MET > 70", treeDraw.clone(selection="met_p4.Et() > 70"))

    ewkDatasets = [
        "WJets", "W1Jets", "W2Jets", "W3Jets", "W4Jets", "TTJets",
        "DYJetsToLL", "SingleTop", "Diboson"
    ]

    if mcOnly:
        eventCounter.normalizeMCToLuminosity(mcOnlyLumi)
    else:
        eventCounter.normalizeMCByLuminosity()
    print "============================================================"
    print mySuffix
    print "============================================================"
    print "Main counter (MC normalized by collision data luminosity)"
    mainTable = eventCounter.getMainCounterTable()
    mainTable.insertColumn(
        2,
        counter.sumColumn(
            "EWKMCsum",
            [mainTable.getColumn(name=name) for name in ewkDatasets]))
    # Default
    #    cellFormat = counter.TableFormatText()
    # No uncertainties
    cellFormat = counter.TableFormatText(cellFormat=counter.CellFormatText(
        valueOnly=False))
    print mainTable.format(cellFormat)

    #    print eventCounter.getSubCounterTable("tauIDTauSelection").format()
    print eventCounter.getSubCounterTable(
        "TauIDPassedEvt::TauSelection_HPS").format(cellFormat)
    print eventCounter.getSubCounterTable(
        "TauIDPassedJets::TauSelection_HPS").format(cellFormat)
    print eventCounter.getSubCounterTable("b-tagging").format(cellFormat)
    print eventCounter.getSubCounterTable("Jet selection").format(cellFormat)
    print eventCounter.getSubCounterTable("Jet main").format(cellFormat)
    print eventCounter.getSubCounterTable("VetoTauSelection").format(
        cellFormat)
    print eventCounter.getSubCounterTable("MuonSelection").format(cellFormat)
    print eventCounter.getSubCounterTable("MCinfo for selected events").format(
        cellFormat)
    print eventCounter.getSubCounterTable("ElectronSelection").format(
        cellFormat)
Beispiel #8
0
def printCounters(datasets):
    eventCounter = counter.EventCounter(datasets)
    eventCounter.normalizeMCByLuminosity()

    ewkDatasets = ["WJets", "TTJets", "DYJetsToLL", "SingleTop", "Diboson"]

    print "============================================================"
    print "Main counter (MC normalized by collision data luminosity)"
    mainTable = eventCounter.getMainCounterTable()
    mainTable.insertColumn(
        2,
        counter.sumColumn(
            "EWKMCsum",
            [mainTable.getColumn(name=name) for name in ewkDatasets]))
    # Default
    #    cellFormat = counter.TableFormatText()
    # No uncertainties
    cellFormat = counter.TableFormatText(cellFormat=counter.CellFormatText(
        valueOnly=True))
    print mainTable.format(cellFormat)
    print eventCounter.getSubCounterTable("MCinfo for selected events").format(
        cellFormat)
Beispiel #9
0
def doCounters(datasets):
    # Create EventCounter object, holds all counters of all datasets
    eventCounter = counter.EventCounter(datasets)

    # Normalize counters
    if mcOnly:
        eventCounter.normalizeMCToLuminosity(mcOnlyLumi)
    else:
        eventCounter.normalizeMCByLuminosity()

    # Create LaTeX format, automatically adjust value precision by uncertainty
    latexFormat = counter.TableFormatLaTeX(
        counter.CellFormatTeX(valueFormat="%.4f", withPrecision=2))
    plainFormat = counter.TableFormatText(
        counter.CellFormatText(valueOnly=True))

    #table = eventCounter.getMainCounterTable()
    #print table.format()

    table = eventCounter.getSubCounterTable("FullHiggsMassCalculator")
    #table.renameRows(counterLabels)
    print table.format(latexFormat)
def printCountersOld(datasets, datasetsMC, analysisPrefix, normalizeToLumi=None):
    print "============================================================"
    print "Dataset info: "
    datasets.printInfo()

    eventCounter = makeEventCounter(datasets)
    if normalizeToLumi == None:
        eventCounter.normalizeMCByLuminosity()
    else:
        eventCounter.normalizeMCToLuminosity(normalizeToLumi)
    
    mainCounterMap = {
        "allEvents": "All events",
        "passedTrigger": "Triggered",
        "passedScrapingVeto": "Scaping veto",
        "passedHBHENoiseFilter": "HBHE noise filter",
        "passedPrimaryVertexFilter": "PV filter",
        analysisPrefix+"countAll": "All events",
        analysisPrefix+"countTrigger": "Triggered",
        analysisPrefix+"countPrimaryVertex": "Good primary vertex",
        analysisPrefix+"countGlobalTrackerMuon": "Global \& tracker muon",
        analysisPrefix+"countMuonKin": "Muon \pT, $\eta$ cuts",
        analysisPrefix+"countMuonQuality": "Muon quality cuts",
        analysisPrefix+"countMuonIP": "Muon transverse IP",
        analysisPrefix+"countMuonVertexDiff": "Muon dz",
        analysisPrefix+"countJetMultiplicityCut": "Njets",
        analysisPrefix+"countMETCut": "MET cut"
        }
    
    latexFormat = counter.TableFormatLaTeX(counter.CellFormatTeX(valueFormat="%.0f"))
    latexFormat2 = counter.TableFormatLaTeX(counter.CellFormatTeX(valueFormat="%.1f"))
    #latexFormat = counter.TableFormatConTeXtTABLE(counter.CellFormatTeX(valueFormat="%.0f", valueOnly=True))
    
    print "============================================================"
    print "Main counter (%s)" % eventCounter.getNormalizationString()
    #eventCounter.getMainCounter().printCounter()
    table = eventCounter.getMainCounterTable()

#    addSumColumn(table)
#    addTtwFractionColumn(table)
#    addPurityColumn(table)
#    addDyFractionColumn(table)
#    addQcdFractionColumn(table)

#    reorderCounterTable(table)

#    print table.format()
    print table.format(latexFormat)
#    print table.format(latexFormat2)
    return
    
    #print "------------------------------------------------------------"
    #print counterEfficiency(eventCounter.getMainCounterTable()).format(FloatDecimalFormat(4))
    
    # mainTable = eventCounter.getMainCounterTable()
    # effTable = counterEfficiency(mainTable)
    # for icol in xrange(0, effTable.getNcolumns()):
    #     column = effTable.getColumn(icol)
    #     column.setName(column.getName()+" eff")
    #     mainTable.insertColumn(icol*2+1, column)
    
    # print "------------------------------------------------------------"
    # printCounter(mainTable, FloatDecimalFormat(4))
    
    
    eventCounter = makeEventCounter(datasetsMC)
    print "============================================================"
    print "Main counter (%s)" % eventCounter.getNormalizationString()
    print eventCounter.getMainCounterTable().format(counter.TableFormatText(counter.CellFormatText(valueOnly=True, valueFormat="%.0f")))
    
    
    # Make the Data column entries comparable to the MC
    table.renameRows(mainCounterMap)
    dataCol = table.getColumn(0)
    table.removeColumn(0)
    dataCol.removeRow(2) # scraping
    dataCol.removeRow(2) # HBHE
    dataCol.removeRow(2) # pv filter
    dataCol.removeRow(2) # all events
    dataCol.removeRow(2) # triggered
    table.insertColumn(0, dataCol)
    addDataMcRatioColumn(table)
    
    # LaTeX tables for note
    latexFormat.setColumnFormat(counter.CellFormatTeX(valueFormat="%.3f"), name="Data/MCsum")
    latexFormat.setColumnFormat(counter.CellFormatTeX(valueFormat="%.1f"), name="SingleTop")
    
    tableDataMc = counter.CounterTable()
    tableDataMc.appendColumn(table.getColumn(name="Data"))
    tableDataMc.appendColumn(table.getColumn(name="MCsum"))
    tableDataMc.appendColumn(table.getColumn(name="Data/MCsum"))
    print tableDataMc.format(latexFormat)
    
    tableMc = counter.CounterTable()
    #tableMc.appendColumn(table.getColumn(name="MCsum"))
    for mcName in datasets.getMCDatasetNames():
        tableMc.appendColumn(table.getColumn(name=mcName))
    print tableMc.format(latexFormat)
    
    tableRatio = counter.CounterTable()
    for cname in ["TTJets/(TTJets+WJets)", "Purity", "QCD/MCsum", "DY/MCsum"]:
        tableRatio.appendColumn(table.getColumn(name=cname))
        latexFormat.setColumnFormat(counter.CellFormatTeX(valueFormat="%.2f", valueOnly=True), name=cname)
    print tableRatio.format(latexFormat)
def main(opts):
    datasets = None
    if len(opts.files) > 0:
        datasets = dataset.getDatasetsFromRootFiles( [(x,x) for x in opts.files], counters=opts.counterdir)
    else:
        datasets = dataset.getDatasetsFromMulticrabCfg(opts=opts, counters=opts.counterdir)

    if os.path.exists(opts.lumifile):
        datasets.loadLuminosities(opts.lumifile)

    if opts.mergeData:
        datasets.mergeData()

    counters = opts.counterdir
    if opts.weighted:
        counters += "/weighted"
    eventCounter = counter.EventCounter(datasets, counters=counters)
    

    print "============================================================"
    if opts.printInfo:
        print "Dataset info: "
        datasets.printInfo()
        print

    quantity = "events"
    if opts.mode == "events":
        pass
    elif opts.mode in ["xsect", "xsection", "crosssection", "crossSection", "eff"]:
        eventCounter.normalizeMCByCrossSection()
        quantity = "MC by cross section, data by events"
    else:
        print "Printing mode '%s' doesn't exist! The following ones are available 'events', 'xsect', 'eff'" % opts.mode
        return 1

    cellFormat = counter.CellFormatText(valueOnly=opts.valueOnly, valueFormat=opts.format)
    formatFunc = lambda table: table.format(counter.TableFormatText(cellFormat))
    csvSplitter = counter.TableSplitter([" +- ", " +", " -"])
    if opts.csv:
        formatFunc = lambda table: table.format(counter.TableFormatText(cellFormat, columnSeparator=","), csvSplitter)
    if opts.mode == "eff":
        cellFormat = counter.CellFormatText(valueFormat="%.4f", valueOnly=opts.valueOnly)
        formatFunc = lambda table: counter.counterEfficiency(table).format(counter.TableFormatText(cellFormat))
        quantity = "Cut efficiencies"
        if opts.csv:
            formatFunc = lambda table: counter.counterEfficiency(table).format(counter.TableFormatText(cellFormat, columnSeparator=","), csvSplitter)

    print "============================================================"
    print "Main counter %s: " % quantity
    print formatFunc(eventCounter.getMainCounterTable())
    print 

    if not opts.mainCounterOnly:
        names = eventCounter.getSubCounterNames()
        names.sort()
        for name in names:
            print "============================================================"
            print "Subcounter %s %s: " % (name, quantity)
            print formatFunc(eventCounter.getSubCounterTable(name))
            print

    # print

    return 0
Beispiel #12
0
print
print
print "From Data"
run(signalAreaEventsFactor, lambda h: h.getHisto("Data").getRootHisto())

#print
#print "From all MC"
#run(signalAreaEventsFactor, lambda h: h.getHisto("StackedMC").getSumRootHisto())

import sys
sys.exit(0)

# Table formatting
tableFormat = counter.TableFormatText()
for i in xrange(1, 19, 2):
    tableFormat.setColumnFormat(counter.CellFormatText(valueFormat="%.5f"),
                                index=i)
#tableFormat = counter.TableFormatConTeXtTABLE(counter.CellFormatTeX(valueOnly=True))


def addEffs(table):
    eff = counter.counterEfficiency(table)
    colnames = eff.getColumnNames()
    mapping = {}
    for n in colnames:
        mapping[n] = n + "_eff"
    eff.renameColumns(mapping)

    for icol in xrange(0, eff.getNcolumns()):
        table.insertColumn(2 * icol + 1, eff.getColumn(icol))
Beispiel #13
0
def main():
    # Read the datasets
    #datasets = dataset.getDatasetsFromMulticrabCfg(counters=counters)
    datasets = dataset.getDatasetsFromMulticrabCfg(analysisName=analysis,
                                                   searchMode=searchMode,
                                                   dataEra=dataEra,
                                                   optimizationMode=optMode)
    datasets.updateNAllEventsToPUWeighted()
    datasets.loadLuminosities()

    plots.mergeRenameReorderForDataMC(datasets)

    # Remove signals other than M120
    ###    datasets.remove(filter(lambda name: "TTToHplus" in name and not "M120" in name, datasets.getAllDatasetNames()))
    #datasets.remove(filter(lambda name: "HplusTB" in name, datasets.getAllDatasetNames()))
    datasets.remove(
        filter(lambda name: "TTToHplusBHminusB" in name,
               datasets.getAllDatasetNames()))
    datasets.remove(
        filter(lambda name: "TTToHplus" in name,
               datasets.getAllDatasetNames()))
    # Set the signal cross sections to a given BR(t->H), BR(h->taunu)
    xsect.setHplusCrossSectionsToBR(datasets, br_tH=0.05, br_Htaunu=1)

    # Set the signal cross sections to a value from MSSM
    #    xsect.setHplusCrossSectionsToMSSM(datasets, tanbeta=20, mu=200)

    ###    plots.mergeWHandHH(datasets) # merging of WH and HH signals must be done after setting the cross section

    style = tdrstyle.TDRStyle()
    eventCounter = counter.EventCounter(datasets)
    #eventCounter = counter.EventCounter(datasets, counters=counters)
    eventCounter.normalizeMCByCrossSection()
    mainTable = eventCounter.getMainCounterTable()
    cellFormat = counter.TableFormatText(cellFormat=counter.CellFormatText(
        valueOnly=True))
    print mainTable.format(cellFormat)

    #eventCounterUnweighted = counter.EventCounter(datasets, mainCounterOnly=True, counters="counters")
    #eventCounterUnweighted.normalizeMCByCrossSection()
    #mainTableUnweighted = eventCounterUnweighted.getMainCounterTable()
    #print mainTableUnweighted.format(cellFormat)

    signalDatasets = [
        "HplusTB_M180",
        "HplusTB_M190",
        "HplusTB_M200",
        "HplusTB_M220",
        "HplusTB_M250",
        "HplusTB_M300",
        #"HplusTB_M400",
        #"HplusTB_M500",
        #"HplusTB_M600",
        #"TTToHplusBWB_M80",
        #"TTToHplusBWB_M90",
        #"TTToHplusBWB_M100",
        #"TTToHplusBWB_M120",
        #"TTToHplusBWB_M140",
        #"TTToHplusBWB_M150",
        #"TTToHplusBWB_M155",
        #"TTToHplusBWB_M160",
    ]
    allName = "Trigger and HLT_MET cut"

    cuts = [
        #"Offline selection begins",
        "Trigger and HLT_MET cut",
        "primary vertex",
        "taus == 1",
        "tau trigger scale factor",
        "electron veto",
        "muon veto",
        "njets",
        "QCD tail killer collinear",
        "MET",
        "btagging",
        "btagging scale factor",
        "QCD tail killer back-to-back"
    ]

    xvalues = [180, 190, 200, 220, 250, 300]
    #xvalues = [80, 90, 100, 120, 140, 150, 155, 160]
    xerrs = [0] * len(xvalues)
    yvalues = {}
    yerrs = {}
    for cut in cuts:
        yvalues[cut] = []
        yerrs[cut] = []
    for name in signalDatasets:
        column = mainTable.getColumn(name=name)
        #columnUnweighted = mainTableUnweighted.getColumn(name=name)

        # Get the counts (returned objects are of type dataset.Count,
        # and have both value and uncertainty
        #allCount = column.getCount(column.getRowNames().index("Trigger and HLT_MET cut"))
        # Somewhat weird way to get total cross section via unweighted counters
        #rowNames = column.getRowNames()
        #if "allEvents" in rowNames:
        #    allCount = columnUnweighted.getCount(rowNames.index("allEvents"))
        #else:
        #    # Hack needed because non-triggered signal pattuples do not have allEvents counter!
        #    allCount = columnUnweighted.getCount(rowNames.index("primaryVertexAllEvents"))
        #dset = datasets.getDataset(name)
        #allCount.multiply(dataset.Count(dset.getNAllEvents()/dset.getNAllEventsUnweighted()))
        allCount = dataset.Count(
            datasets.getDataset(name).getCrossSection(), 0)

        for cut in cuts:
            cutCount = column.getCount(column.getRowNames().index(cut))
            eff = cutCount.clone()
            eff.divide(allCount)  # N(cut) / N(all)
            if column.getRowNames().index(cut) == 9:  ## btagging
                print cut, eff.value()
            yvalues[cut].append(eff.value())
            yerrs[cut].append(eff.uncertainty())

    def createErrors(cutname):
        gr = ROOT.TGraphErrors(len(xvalues), array.array("d", xvalues),
                               array.array("d", yvalues[cutname]),
                               array.array("d", xerrs),
                               array.array("d", yerrs[cutname]))
        gr.SetMarkerStyle(24)
        gr.SetMarkerColor(2)
        gr.SetMarkerSize(0.9)
        gr.SetLineStyle(1)
        gr.SetLineWidth(2)
        return gr

    #gtrig = createErrors("primary vertex")
    gtrig = createErrors("Trigger and HLT_MET cut")
    print gtrig
    gtrig.SetLineColor(38)
    gtrig.SetMarkerColor(38)
    gtrig.SetMarkerStyle(20)
    gtrig.SetLineStyle(2)
    gtrig.SetMarkerSize(2)

    gtau = createErrors("taus == 1")
    gtau.SetLineColor(2)
    gtau.SetMarkerColor(2)
    gtau.SetMarkerStyle(20)
    gtau.SetMarkerSize(2)
    gtau.SetLineStyle(3)
    #gtau = createErrors("trigger scale factor")

    gveto = createErrors("muon veto")
    gveto.SetLineColor(1)
    gveto.SetMarkerColor(1)
    gveto.SetMarkerStyle(21)
    gveto.SetMarkerSize(2)
    gveto.SetLineStyle(4)
    gjets = createErrors("njets")
    gjets.SetLineColor(4)
    gjets.SetMarkerColor(4)
    gjets.SetMarkerStyle(22)
    gjets.SetMarkerSize(2)
    gjets.SetLineStyle(1)
    gcoll = createErrors("QCD tail killer collinear")
    gcoll.SetLineColor(6)
    gcoll.SetMarkerColor(6)
    gcoll.SetMarkerStyle(26)
    gcoll.SetMarkerSize(2)
    gcoll.SetLineStyle(2)
    gmet = createErrors("MET")
    gmet.SetLineColor(1)
    gmet.SetMarkerColor(1)
    gmet.SetMarkerStyle(24)
    gmet.SetMarkerSize(2)
    gmet.SetLineStyle(5)
    gbtag = createErrors("btagging")
    gbtag.SetLineColor(2)
    gbtag.SetMarkerColor(2)
    gbtag.SetMarkerStyle(25)
    gbtag.SetMarkerSize(2)
    gbtag.SetLineStyle(6)
    print gbtag
    gback = createErrors("QCD tail killer back-to-back")
    gback.SetLineColor(7)
    gback.SetMarkerColor(7)
    gback.SetMarkerStyle(23)
    gback.SetMarkerSize(2)
    gback.SetLineStyle(1)
    #gtau = createErrors("trigger scale factor")

    glist = [gtrig, gtau, gveto, gjets, gcoll, gmet, gbtag, gback]

    opts = {"xmin": 175, "xmax": 310, "ymin": 0.001}
    canvasFrame = histograms.CanvasFrame(
        [histograms.HistoGraph(g, "", "") for g in glist], "SignalEfficiency",
        **opts)
    canvasFrame.frame.GetYaxis().SetTitle("Selection efficiency")
    canvasFrame.frame.GetXaxis().SetTitle("m_{H^{#pm}} (GeV/c^{2})")
    canvasFrame.canvas.SetLogy(True)
    canvasFrame.frame.Draw()

    for gr in glist:
        gr.Draw("PC same")

    histograms.addStandardTexts()

    legend2 = histograms.createLegend(x1=0.5, y1=0.7, x2=0.9, y2=0.85)

    legend2.AddEntry(gtrig, "Trigger", "lp")
    legend2.AddEntry(gtau, "Loose #tau identification", "lp")
    legend2.AddEntry(gveto, "lepton vetoes", "lp")
    legend2.AddEntry(gjets, "3 jets", "lp")
    legend2.Draw()

    legend = histograms.createLegend(x1=0.35, y1=0.15, x2=0.7, y2=0.3)
    legend.AddEntry(gcoll, "QCD tail killer collinear", "lp")
    legend.AddEntry(gmet, "MET > 60 GeV", "lp")
    legend.AddEntry(gbtag, "b tagging ", "lp")
    legend.AddEntry(gback, "QCD tail killer back-to-back: Tight", "lp")
    legend.Draw()
    canvasFrame.canvas.SaveAs(".png")
    canvasFrame.canvas.SaveAs(".C")
    canvasFrame.canvas.SaveAs(".eps")
def doCounters(datasets):
    # Counters
    eventCounter = counter.EventCounter(datasets, counters=counters)
    mainCounter = eventCounter.getMainCounter()

    selectionsCumulative = []
    tauSelectionsCumulative = []
    td = treeDraw.clone(weight="")

    def sel(name, selection):
        selectionsCumulative.append(selection)
        sel = selectionsCumulative[:]
        if len(tauSelectionsCumulative) > 0:
            sel += ["Sum$(%s) >= 1" % "&&".join(tauSelectionsCumulative)]
        mainCounter.appendRow(name, td.clone(selection="&&".join(sel)))

    def tauSel(name, selection):
        tauSelectionsCumulative.append(selection)
        sel = selectionsCumulative[:]
        if len(tauSelectionsCumulative) > 0:
            sel += ["Sum$(%s) >= 1" % "&&".join(tauSelectionsCumulative)]
        mainCounter.appendRow(name, td.clone(selection="&&".join(sel)))

    sel("Primary vertex", pvSelection)

    sel(">= 1 tau candidate", "Length$(taus_p4) >= 1")
    tauSel("Decay mode finding", decayModeFinding)
    tauSel("pT > 15", "(taus_p4.Pt() > 15)")
    tauSel("pT > 40", tauPtCut)  #
    tauSel("eta < 2.1", tauEtaCut)
    tauSel("leading track pT > 20", tauLeadPt)
    tauSel("ECAL fiducial", ecalFiducial)
    tauSel("againstElectron", electronRejection)  #
    tauSel("againstMuon", muonRejection)
    tauSel("isolation", tightIsolation)  #
    tauSel("oneProng", oneProng)  #
    tauSel("Rtau", rtau)  #

    sel("3 jets", jetEventSelection)
    sel("MET", metSelection)
    sel("btag", btagEventSelection)
    sel("deltaPhi<160", deltaPhi160Selection)

    fullSelection = "&&".join(
        selectionsCumulative +
        ["Sum$(%s) >= 1" % "&&".join(tauSelectionsCumulative)])
    fullSelectionCaloMetNoHF = fullSelection + "&&" + caloMetNoHF
    fullSelectionCaloMet = fullSelection + "&&" + caloMet
    #print fullSelection
    f = open("pickEvents.txt", "w")

    def printPickEvent(tree):
        f.write("%d:%d:%d\n" % (tree.run, tree.lumi, tree.event))

    ts = dataset.TreeScan(td.tree,
                          function=printPickEvent,
                          selection=fullSelection)
    ts2 = dataset.TreeScan(td.tree,
                           function=printPickEvent,
                           selection=fullSelectionCaloMetNoHF)
    ts3 = dataset.TreeScan(td.tree,
                           function=printPickEvent,
                           selection=fullSelectionCaloMet)
    ts4 = dataset.TreeDrawCompound(
        ts2, {
            "SingleMu_Mu_170722-172619_Aug05": ts3,
            "SingleMu_Mu_172620-173198_Prompt": ts3,
            "SingleMu_Mu_173236-173692_Prompt": ts3,
        })
    datasets.getDataset("Data").getDatasetRootHisto(ts4)
    f.close()

    ewkDatasets = [
        "WJets",
        "TTJets",
        #        "DYJetsToLL", "SingleTop", "Diboson"
    ]

    eventCounter.normalizeMCByLuminosity()
    mainTable = eventCounter.getMainCounterTable()
    #mainTable.insertColumn(2, counter.sumColumn("EWKMCsum", [mainTable.getColumn(name=name) for name in ewkDatasets]))
    cellFormat = counter.TableFormatText(
        counter.CellFormatText(valueFormat='%.3f',
                               #valueOnly=True
                               ),
        #                                         columnSeparator = ";",
    )
    print mainTable.format(cellFormat)

    return

    effFormat = counter.TableFormatText(
        counter.CellFormatTeX(valueFormat='%.4f'))
    effTable = counter.CounterTable()
    col = table.getColumn(name="Data")
    effTable.appendColumn(col)
    effTable.appendColumn(counter.efficiencyColumn(col.getName() + " eff",
                                                   col))
    col = table.getColumn(name="EWKMCsum")
    effTable.appendColumn(col)
    effTable.appendColumn(counter.efficiencyColumn(col.getName() + " eff",
                                                   col))
    print effTable.format(effFormat)
def doTauCounters(datasetsEmb,
                  datasetsSig,
                  datasetName,
                  ntupleCacheEmb,
                  ntupleCacheSig,
                  normalizeEmb=True):
    lumi = datasetsEmb.getLuminosity()

    # Take unweighted counters for embedded, to get a handle on the muon isolation efficiency
    eventCounterEmb = tauEmbedding.EventCounterMany(
        datasetsEmb,
        counters="/" + tauAnalysisEmb + "Counters",
        normalize=normalizeEmb)
    eventCounterSig = counter.EventCounter(datasetsSig,
                                           counters="/" + tauAnalysisEmb +
                                           "Counters")

    def isNotThis(name):
        return name != datasetName

    eventCounterEmb.removeColumns(
        filter(isNotThis, datasetsEmb.getAllDatasetNames()))
    eventCounterSig.removeColumns(
        filter(isNotThis, datasetsSig.getAllDatasetNames()))

    eventCounterEmb.mainCounterAppendRows(
        ntupleCacheEmb.histogram("counters/weighted/counter"))
    eventCounterSig.getMainCounter().appendRows(
        ntupleCacheSig.histogram("counters/weighted/counter"))

    eventCounterSig.normalizeMCToLuminosity(lumi)

    table = counter.CounterTable()
    col = eventCounterEmb.getMainCounterTable().getColumn(name=datasetName)
    col.setName("Embedded")
    table.appendColumn(col)
    col = eventCounterSig.getMainCounterTable().getColumn(name=datasetName)
    col.setName("Normal")
    table.appendColumn(col)

    lastCountEmb = table.getCount(colName="Embedded",
                                  irow=table.getNrows() - 1)
    lastCountNormal = table.getCount(colName="Normal",
                                     irow=table.getNrows() - 1)

    postfix = ""
    if not normalizeEmb:
        postfix = "_notEmbNormalized"

    effFormat = counter.TableFormatLaTeX(
        counter.CellFormatTeX(valueFormat="%.4f", withPrecision=2))
    countFormat = counter.TableFormatText(
        counter.CellFormatText(valueFormat="%.4f"),
        #columnSeparator="  ;"
    )

    fname = "counters_tau_" + datasetName + postfix + ".txt"
    f = open(fname, "w")
    f.write(table.format(countFormat))
    f.write("\n")

    try:
        ratio = lastCountNormal.clone()
        ratio.divide(lastCountEmb)
        f.write("Normal/embedded = %.4f +- %.4f\n\n" %
                (ratio.value(), ratio.uncertainty()))
    except ZeroDivisionError:
        pass

    f.close()
    print "Printed tau counters to", fname

    if not normalizeEmb:
        return

    tableEff = counter.CounterTable()
    tableEff.appendColumn(
        counter.efficiencyColumn("Embedded eff",
                                 table.getColumn(name="Embedded")))
    tableEff.appendColumn(
        counter.efficiencyColumn("Normal eff", table.getColumn(name="Normal")))

    embeddingMuonIsolationEff = tableEff.getCount(
        rowName="tauEmbeddingMuonsCount", colName="Embedded eff")
    embeddingTauIsolationEff = tableEff.getCount(rowName="Isolation",
                                                 colName="Embedded eff")
    embeddingTotalIsolationEff = embeddingMuonIsolationEff.clone()
    embeddingTotalIsolationEff.multiply(embeddingTauIsolationEff)

    # Remove unnecessary rows
    rowNames = [
        #        "All events",
        "Decay mode finding",
        "Eta cut",
        "Pt cut",
        "Leading track pt",
        "Against electron",
        "Against muon",
        "Isolation",
        "One prong",
        "Rtau",
    ]
    tableEff.keepOnlyRows(rowNames)
    rowIndex = tableEff.getRowNames().index("Isolation")
    tableEff.insertRow(
        rowIndex,
        counter.CounterRow("Mu isolation (emb)",
                           ["Embedded eff", "Normal eff"],
                           [embeddingMuonIsolationEff, None]))
    tableEff.insertRow(
        rowIndex + 1,
        counter.CounterRow("Tau isolation (emb)",
                           ["Embedded eff", "Normal eff"],
                           [embeddingTauIsolationEff, None]))
    tableEff.setCount2(embeddingTotalIsolationEff,
                       rowName="Isolation",
                       colName="Embedded eff")
    #tableEff.setCount2(None, rowName="pT > 15", colName="Normal eff")

    #print table.format(effFormat)
    fname = "counters_tau_" + datasetName + "_eff.txt"
    f = open(fname, "w")
    f.write(tableEff.format(effFormat))
    f.write("\n")
    f.close()
    print "Printed tau efficiencies to", fname
Beispiel #16
0
print "============================================================"
print "Main counter (MC normalized by collision data luminosity)"
print eventCounter.getMainCounterTable().format()

# Example how to print all subcounter names
for subCounterName in eventCounter.getSubCounterNames():
    print "============================================================"
    print "Subcounter %s (MC normalized by collision data luminosity)" % subCounterName
    print eventCounter.getSubCounterTable(subCounterName).format()

print "============================================================"
print "Main counter (examples of the same table)"

# Change the value format (printf style)
print eventCounter.getMainCounterTable().format(
    counter.TableFormatText(counter.CellFormatText(valueFormat="%.1f")))

# No uncertainties
print eventCounter.getMainCounterTable().format(
    counter.TableFormatText(
        counter.CellFormatText(valueFormat="%.0e", valueOnly=True)))

# LaTeX table (tabular), default format
print eventCounter.getMainCounterTable().format(counter.TableFormatLaTeX())

# LaTeX table, change value and uncertainty formats
print eventCounter.getMainCounterTable().format(
    counter.TableFormatLaTeX(
        counter.CellFormatTeX(valueFormat="%.2e",
                              uncertaintyFormat="%.1e",
                              uncertaintyPrecision=1)))
eventCounter.normalizeMCToLuminosity(33.69)

# Example how to print the main counter with the default formatting
print "============================================================"
print "Main counter (MC normalized by collision data luminosity)"
print eventCounter.getMainCounterTable().format()

# Example how to print all subcounter names
for subCounterName in eventCounter.getSubCounterNames():
    print "============================================================"
    print "Subcounter %s (MC normalized by collision data luminosity)" % subCounterName
    print eventCounter.getSubCounterTable(subCounterName).format()


print "============================================================"
print "Main counter (examples of the same table)"

# Change the value format (printf style)
print eventCounter.getMainCounterTable().format(counter.TableFormatText(counter.CellFormatText(valueFormat="%.1f")))

# No uncertainties
print eventCounter.getMainCounterTable().format(counter.TableFormatText(counter.CellFormatText(valueFormat="%.0e", valueOnly=True)))

# LaTeX table (tabular), default format
print eventCounter.getMainCounterTable().format(counter.TableFormatLaTeX())

# LaTeX table, change value and uncertainty formats
print eventCounter.getMainCounterTable().format(counter.TableFormatLaTeX(counter.CellFormatTeX(valueFormat="%.2e", uncertaintyFormat="%.1e", uncertaintyPrecision=1)))


def process(datasets, datasetName, postfix, countName):
    # Handle counter
    eventCounter = counter.EventCounter(datasets)
    mainTable = eventCounter.getMainCounterTable()

    neventsCount = mainTable.getCount(rowName=countName, colName=datasetName)
    nevents = neventsCount.value()
#    column = eventCounter.getSubCounterTable("Classification"+postfix).getColumn(name=datasetName)
#
#    columnFraction = column.clone()
#    columnFraction.setName("Fraction (%)")
#
#    # Consistency check, and do the division
#    tmp = 0
#    for irow in xrange(column.getNrows()):
#        tmp += column.getCount(irow).value()
#
#        frac = dataset.divideBinomial(columnFraction.getCount(irow), neventsCount)
#        frac.multiply(dataset.Count(100))
#        columnFraction.setCount(irow, frac)
#
#    if int(nevents) != int(tmp):
#        raise Exception("Consistency check failed: nevents = %d, tmp = %d" % (int(nevents), int(tmp)))
#
    table = counter.CounterTable()
#    table.appendColumn(column)
#    table.appendColumn(columnFraction)
#
    cellFormat = counter.CellFormatText(valueFormat='%.4f', withPrecision=2)
    tableFormat = counter.TableFormatText(cellFormat)

    print
    print "Dataset %s, step %s, nevents %d" % (datasetName, postfix, int(nevents))
    print table.format(tableFormat)

    # Make plots
    dset = datasets.getDataset(datasetName)
    tmp = Counts()
    oldCanvasDefW = ROOT.gStyle.GetCanvasDefW()
    ROOT.gStyle.SetCanvasDefW(int(oldCanvasDefW*1.5))

    # (tauID, leptonVeto)
    def usualRejected(obj2):
        _tauIDLabels = tauIDLabels(obj2)
        ret = [("None", "None"), ("None", "#tau_{1}")]
        ret.extend([(x, "#tau_{1}") for x in _tauIDLabels[4:]])
        ret.extend([(x, obj2) for x in _tauIDLabels])
        ret.extend([(x, "Other") for x in _tauIDLabels])
        return ret
    usualEmbedding = [("#tau_{1}", "None"), ("#tau_{1}+other (corr. sel.)", "None")]
    def usualFakeTau(obj2):
        return [(x, "None") for x in tauIDLabels(obj2)[4:]]
    doubleFakeTau = [("Other", "None")]
    usualCase1 = [(x, "#tau_{1}") for x in tauIDLabels("")[1:4]]
    usualCase3 = [("#tau_{1}+other (wrong sel.)", "None")]
    embCase4 = [(x, "None") for x in tauIDLabels("")[1:4]]
    def doubleCase2(obj2):
        return [(obj2, "None"), (obj2+"+other", "None")]

    selectionStep = {"Before": "",
                     "AfterJetSelection": "passJetSelection",
                     "AfterMET": "passMET",
                     "AfterBTag": "passBTag",
                     "AfterAllSelections": "passDeltaPhi"}[postfix]

    treeDraw = dataset.TreeDraw("tree", varexp="LeptonVetoStatus:TauIDStatus >>htemp(%d,0,%d, %d,0,%d" % (Enum.tauSize, Enum.tauSize, Enum.leptonSize, Enum.leptonSize))

    for name, obj2, obj2Type in [
        ("tau1_electron2", "e_{2}", Enum.obj2Electron),
        ("tau1_quark2", "q_{2}", Enum.obj2Quark),
        ("tau1_muon2_nonEmb", "#mu_{2}", Enum.obj2Muon),
        ]:
        tmp += calculatePlot(dset, neventsCount, name, postfix,
                             treeDraw=treeDraw.clone(selection=And("Obj2Type==%d"%obj2Type, selectionStep), binLabelsX=tauIDLabels(obj2), binLabelsY=leptonVetoLabels(obj2)),
                             rejected=usualRejected(obj2), embedding=usualEmbedding, faketau=usualFakeTau(obj2),
                             case1=usualCase1, case3=usualCase3)

    tmp += calculatePlot(dset, neventsCount, "tau1_muon2_Emb", postfix,
                         treeDraw=treeDraw.clone(selection=And("Obj2Type==%d"%Enum.obj2MuonEmb, selectionStep), binLabelsX=tauIDLabels("#mu_{2}"), binLabelsY=leptonVetoLabels("#mu_{2}")),
                         rejected=usualRejected("#mu_{2}")+usualCase1,
                         faketau=usualFakeTau("#mu_{2}"),
                         case4=embCase4)
#    createMuon2Plot(dset, "tau1_muon2_Emb", postfix)

    for name, obj2, obj2Type in [
        ("tau1_tau2_notInAcceptance", "#tau_{2}", Enum.obj2TauNotInAcceptance),
        ("tau1_tauh2", "#tau_{h,2}", Enum.obj2Tauh),
        ("tau1_taue2", "#tau_{e,2}", Enum.obj2Taue),
        ("tau1_taumu2_nonEmb", "#tau_{#mu,2}", Enum.obj2Taumu),
        ]:
        tmp += calculatePlot(dset, neventsCount, name, postfix,
                             treeDraw=treeDraw.clone(selection=And("Obj2Type==%d"%obj2Type, selectionStep), binLabelsX=tauIDLabels(obj2), binLabelsY=leptonVetoLabels(obj2)),
                             rejected=usualRejected(obj2), embedding=usualEmbedding, faketau=doubleFakeTau,
                             case1=usualCase1, case3=usualCase3,
                             case2=doubleCase2(obj2))

    tmp += calculatePlot(dset, neventsCount, "tau1_taumu2_Emb", postfix,
                         treeDraw=treeDraw.clone(selection=And("Obj2Type==%d"%Enum.obj2TaumuEmb, selectionStep), binLabelsX=tauIDLabels("#tau_{#mu,2}"), binLabelsY=leptonVetoLabels("#tau_{#mu,2}")),
                         rejected=usualRejected("#tau_{#mu,2}")+usualCase1,
                         faketau=doubleFakeTau,
                         case4=embCase4)

    ROOT.gStyle.SetCanvasDefW(oldCanvasDefW)


    ## Ntuple stuff

    embeddingSelection = Or(*[And("Obj2Type == %d"%obj2, "LeptonVetoStatus == %d"%Enum.leptonNone, Or(*["TauIDStatus == %d" % x for x in [Enum.tauTau1, Enum.tauTau1OtherCorrect]]))
                              for obj2 in [Enum.obj2Electron, Enum.obj2Quark, Enum.obj2Muon, Enum.obj2TauNotInAcceptance, Enum.obj2Tauh, Enum.obj2Taue, Enum.obj2Taumu]])
    case1Selection = Or(*[And("Obj2Type == %d"%obj2, "LeptonVetoStatus == %d"%Enum.leptonTau1, Or(*["TauIDStatus == %d" % x for x in [Enum.tauTau1, Enum.tauTau1OtherCorrect, Enum.tauTau1OtherWrong]]))
                              for obj2 in [Enum.obj2Electron, Enum.obj2Quark, Enum.obj2Muon, Enum.obj2TauNotInAcceptance, Enum.obj2Tauh, Enum.obj2Taue, Enum.obj2Taumu]])
    case2Selection = Or(*[And("Obj2Type == %d"%obj2, "LeptonVetoStatus == %d"%Enum.leptonNone, Or(*["TauIDStatus == %d" % x for x in [Enum.tauObj2, Enum.tauObj2Other]]))
                              for obj2 in [Enum.obj2TauNotInAcceptance, Enum.obj2Tauh, Enum.obj2Taue, Enum.obj2Taumu]])

    embeddingSelection = And(selectionStep, embeddingSelection)
    case1Selection = And(selectionStep, case1Selection)
    case2Selection = And(selectionStep, case2Selection)
    
    createTransverseMassPlot(dset, "case1", postfix, nominalSelection=embeddingSelection, compareSelection=case1Selection,
                             nominalLegend="Embedding (correct)", compareLegend="Case 1")
    createTransverseMassPlot(dset, "case2", postfix, nominalSelection=embeddingSelection, compareSelection=case2Selection,
                             nominalLegend="Embedding (correct)", compareLegend="Case 2")

    # plotNames = [
    #             "tau1_electron2",
    #             "tau1_quark2",
    #             "tau1_muon2_nonEmb",     
    #             "tau1_muon2_Emb",
    #             "tau1_tau2_notInAcceptance",
    #             "tau1_tauh2", 
    #             "tau1_taue2",
    #             "tau1_taumu2_nonEmb",
    #             "tau1_taumu2_Emb"
    #             ]
    # for name in plotNames:
    #     tmp += calculatePlot(dset, neventsCount, name, postfix)

    if int(nevents) != int(tmp.all):
        raise Exception("Consistency check failed: nevents = %d, tmp = %d" % (int(nevents), int(tmp.all)))

    tmp.printResults()
    print
    tmp.printLegend()
    tmp.crossCheck()

    allEmbeddingIncluded = int(tmp.embedding) + int(tmp.case1) + int(tmp.case3)

    print
    print "So, the number of events included by embedding is %d" % allEmbeddingIncluded
    print "Of these,"
 
    frac = dataset.divideBinomial(dataset.Count(int(tmp.embedding)), dataset.Count(allEmbeddingIncluded))
    frac.multiply(dataset.Count(100))
    print "  * %d (%s %%) are included correctly" % (int(tmp.embedding), cellFormat.format(frac))

    frac = dataset.divideBinomial(dataset.Count(int(tmp.case3)), dataset.Count(allEmbeddingIncluded))
    frac.multiply(dataset.Count(100))
    print "  * %d (%s %%) are included correctly, but wrong object is chosen as tau_h" % (int(tmp.case3), cellFormat.format(frac))

    frac = dataset.divideBinomial(dataset.Count(int(tmp.case1)), dataset.Count(allEmbeddingIncluded))
    frac.multiply(dataset.Count(100))
    print "  * %d (%s %%) are included incorrectly (tau_1 identified in lepton veto)" % (int(tmp.case1), cellFormat.format(frac))

    print "In addition, the following events are incorrectly rejected"
    # Note that these ratios are NOT binomial!
    # Although apparently, in practice, the result is the same
    
    #frac = dataset.divideBinomial(dataset.Count(int(tmp.case2)), dataset.Count(allEmbeddingIncluded))
    frac = dataset.Count(tmp.case2, math.sqrt(tmp.case2))
    frac.divide(dataset.Count(allEmbeddingIncluded, math.sqrt(allEmbeddingIncluded)))
    frac.multiply(dataset.Count(100))
    print "  * %d (%s %%): tau_1 not identified as tau_h, but decay of tau_2 would be" % (int(tmp.case2), cellFormat.format(frac))

    #frac = dataset.divideBinomial(dataset.Count(int(tmp.case4)), dataset.Count(allEmbeddingIncluded))
    frac = dataset.Count(tmp.case4, math.sqrt(tmp.case4))
    frac.divide(dataset.Count(allEmbeddingIncluded, math.sqrt(allEmbeddingIncluded)))
    frac.multiply(dataset.Count(100))
    print "  * %d (%s %%): mu_2 would be accepted for embedding, and is not identified in lepton veto" % (int(tmp.case4), cellFormat.format(frac))