Esempio n. 1
0
def stackinputs(file, variable, processes, **kwargs):
    """Stack histograms from ROOT file.
       file:       TFile or TDirectory object
       variable:  Variables object
       processes: list of strings (name of processes)
     e.g.
       stackinputs(file,variable,['ZTT','TTT','W','QCD','data_obs'])
  """
    text = kwargs.get('text', None)
    tag = kwargs.get('tag', "")
    groups = kwargs.get('group', [])  # e.g. [(['^TT','ST'],'Top')]
    dname = kwargs.get('dname', None)  # directory ('bin') name
    pname = kwargs.get('save', "stack$TAG.png")  # save as image file
    wname = kwargs.get('write', "stack$TAG")  # write to file
    style = kwargs.get('style', False)  # write style to file

    exphists = []
    datahist = None
    tdir = ensureTDirectory(file, dname, cd=True) if dname else file
    if style:
        gStyle.Write(
            'style',
            TH1.kOverwrite)  # write current TStyle object to reproduce plots
    for process in processes:
        hname = process
        hist = gethist(tdir, process, fatal=False, warn=False)
        if not hist:
            LOG.warning(
                "stackinputs: Could not find %r in %s. Skipping stacked plot..."
                % (process, tdir.GetPath()))
            return
        hist.SetDirectory(0)
        hist.SetLineColor(kBlack)
        hist.SetFillStyle(1001)  # assume fill color is already correct
        if process == 'data_obs':
            datahist = hist
        else:
            exphists.append(hist)
    for group in groups:
        grouphists(exphists, *group, replace=True, regex=True, verb=0)
    stack = Stack(variable, datahist, exphists)
    stack.draw()
    stack.drawlegend(ncols=2, twidth=0.9)
    if text:
        stack.drawtext(text)
    if pname:
        pname = repkey(pname, TAG=tag)
        stack.saveas(pname, ext=['png'])
    if wname:
        wname = repkey(wname, TAG=tag)
        stack.canvas.Write(wname, TH1.kOverwrite)
    stack.close()
Esempio n. 2
0
def comparevars(file, variable, processes, systag, **kwargs):
    """Compare up/down variations of input histograms from ROOT file.
       file:      TFile or TDirectory object
       variable:  Variables object
       processes: list of strings (name of processes)
       systag:    string of systematic (file must contain up/down variation)
     e.g.
       comparevars(file,variable,['ZTT','TTT'],'TES')
  """
    text = kwargs.get('text', None)
    pname = kwargs.get('pname', "stack.png")
    tag = kwargs.get('tag', "")
    groups = kwargs.get('group', [])  # e.g. [(['^TT','ST'],'Top')]
    dname = kwargs.get('dname', None)  # directory ('bin') name
    pname = kwargs.get('save', "plot_$PROC$SYST$TAG.png")  # save as image file
    wname = kwargs.get('write', "plot_$PROC$SYST$TAG")  # write to file
    processes = ensurelist(processes)
    uptag = systag + "Up"
    downtag = systag + "Down"
    tdir = ensureTDirectory(file, dname, cd=True) if dname else file
    for process in processes:
        hists = []
        skip = False
        for var in [uptag, "", downtag]:
            hname = process + var
            hist = gethist(tdir, hname, fatal=False, warn=False)
            if not hist:
                skip = True
                break
            hists.append(hist)
        if skip:
            LOG.warning(
                "comparevars: Could not find %r in %s. Skipping shape comparison..."
                % (hname, tdir.GetPath()))
            continue
        plot = Plot(variable, hists)
        plot.draw(ratio=2, lstyle=1)
        plot.drawlegend()
        if text:
            plot.drawtext(text)
        if pname:
            pname_ = repkey(pname, PROC=process, TAG=tag)
            plot.saveas(pname_, ext=['png'])
        if wname:
            wname_ = repkey(wname, PROC=process, TAG=tag)
            plot.canvas.Write(wname_, TH1.kOverwrite)
        plot.close()
Esempio n. 3
0
def createinputs(fname, sampleset, observables, bins, **kwargs):
    """Create histogram inputs in ROOT file for datacards.
       fname:       filename pattern of ROOT file
       sampleset:   SampleSet object
       observables: list of Variables objects
       bins:        list of Selection objects
  """
    #LOG.header("createinputs")
    outdir = kwargs.get('outdir', "")
    tag = kwargs.get('tag', "")  # file tag
    htag = kwargs.get('htag', "")  # hist tag for systematic
    filters = kwargs.get('filter',
                         None)  # only create histograms for these processes
    vetoes = kwargs.get('veto', None)  # veto these processes
    parallel = kwargs.get('parallel', True)  # MultiDraw histograms in parallel
    recreate = kwargs.get('recreate', False)  # recreate ROOT file
    replaceweight = kwargs.get('replaceweight', None)  # replace weight
    extraweight = kwargs.get('weight', "")  # extraweight
    shiftQCD = kwargs.get('shiftQCD', 0)  # e.g 0.30 for 30%
    verbosity = kwargs.get('verb', 0)
    option = 'RECREATE' if recreate else 'UPDATE'
    method = 'QCD_OSSS' if filters == None or 'QCD' in filters else None
    method = kwargs.get('method', method)

    # FILE LOGISTICS: prepare file and directories
    files = {}
    ensuredir(outdir)
    fname = os.path.join(outdir, fname)
    for obs in observables:
        obsname = obs.filename
        ftag = tag + obs.tag
        fname_ = repkey(fname, OBS=obsname, TAG=tag)
        file = TFile.Open(fname_, option)
        if recreate:
            print ">>> created file %s" % (fname_)
        for selection in bins:
            if not obs.plotfor(selection): continue
            obs.changecontext(selection)
            ensureTDirectory(file, selection.filename, cd=True, verb=verbosity)
            if recreate:
                string = joincuts(selection.selection, obs.cut)
                TNamed("selection", string).Write(
                )  # write exact selection string to ROOT file for the record / debugging
                #TNamed("weight",sampleset.weight).Write()
                LOG.verb(
                    "%s selection %r: %r" % (obsname, selection.name, string),
                    verbosity, 1)
        files[obs] = file

    # GET HISTS
    for selection in bins:
        bin = selection.filename  # bin name
        print ">>>\n>>> " + color(
            " %s " % (bin), 'magenta', bold=True, ul=True)
        if htag:
            print ">>> systematic uncertainty: %s" % (color(
                htag.lstrip('_'), 'grey'))
        if recreate or verbosity >= 1:
            print ">>> %r" % (selection.selection)
        hists = sampleset.gethists(observables,
                                   selection,
                                   method=method,
                                   split=True,
                                   parallel=parallel,
                                   filter=filters,
                                   veto=vetoes)

        # SAVE HIST
        ljust = 4 + max(11, len(htag))  # extra space
        TAB = LOG.table("%10.1f %10d  %-18s  %s")
        TAB.printheader('events', 'entries', 'variable',
                        'process'.ljust(ljust))
        for obs, hist in hists.iterhists():
            name = lreplace(hist.GetName(), obs.filename).strip(
                '_')  # histname = $VAR_$NAME (see Sample.gethist)
            if not name.endswith(htag):
                name += htag  # HIST = $PROCESS_$SYSTEMATIC
            name = repkey(name, BIN=bin)
            drawopt = 'E1' if 'data' in name else 'EHIST'
            lcolor = kBlack if any(
                s in name
                for s in ['data', 'ST', 'VV']) else hist.GetFillColor()
            hist.SetOption(drawopt)
            hist.SetLineColor(lcolor)
            hist.SetFillStyle(0)  # no fill in ROOT file
            hist.SetName(name)
            hist.GetXaxis().SetTitle(obs.title)
            for i, yval in enumerate(hist):
                if yval < 0:
                    print ">>> replace bin %d (%.3f<0) of %r" % (
                        i, yval, hist.GetName())
                    hist.SetBinContent(i, 0)
            files[obs].cd(bin)  # $FILE:$BIN/$PROCESS_$SYSTEMATC
            hist.Write(name, TH1.kOverwrite)
            TAB.printrow(hist.GetSumOfWeights(), hist.GetEntries(),
                         obs.printbins(), name)
            deletehist(hist)  # clean memory

    # CLOSE
    for obs, file in files.iteritems():
        file.Close()
Esempio n. 4
0
def plotinputs(fname, varprocs, observables, bins, **kwargs):
    """Plot histogram inputs from ROOT file for datacards, and write to ROOT file.
       fname:       filename pattern of ROOT file
       varprocs:    dictionary for systematic variation to list of processes,
                    e.g. { 'Nom':   ['ZTT','TTT','W','QCD','data_obs'],
                           'TESUp': ['ZTT','TTT'], 'TESDown': ['ZTT','TTT'] }
       observables: list of Variables objects
       bins:        list of Selection objects
  """
    #LOG.header("plotinputs")
    tag = kwargs.get('tag', "")
    pname = kwargs.get('pname', "$OBS_$BIN$TAG.png")
    outdir = kwargs.get('outdir', 'plots')
    text = kwargs.get('text', "$BIN")
    groups = kwargs.get('group',
                        [])  # add processes together into one histogram
    verbosity = kwargs.get('verb', 0)
    ensuredir(outdir)
    print ">>>\n>>> " + color(" plotting... ", 'magenta', bold=True, ul=True)
    for obs in observables:
        obsname = obs.filename
        ftag = tag + obs.tag
        fname_ = repkey(fname, OBS=obsname, TAG=ftag)
        file = ensureTFile(fname_, 'UPDATE')
        for set, procs in varprocs.iteritems(
        ):  # loop over processes with variation
            if set == 'Nom':
                systag = ""  # no systematics tag for nominal
                procs_ = procs[:]
            else:
                systag = '_' + set  # systematics tag for variation, e.g. '_TESUp'
                procs_ = [
                    (p + systag if p in procs else p) for p in varprocs['Nom']
                ]  # add tag to varied processes
            for selection in bins:
                if not obs.plotfor(selection): continue
                obs.changecontext(selection)
                bin = selection.filename
                text_ = repkey(
                    text, BIN=selection.title)  # extra text in plot corner
                tdir = ensureTDirectory(file, bin,
                                        cd=True)  # directory with histograms
                if set == 'Nom':
                    gStyle.Write(
                        'style', TH1.kOverwrite
                    )  # write current TStyle object to reproduce plots

                # STACKS
                pname_ = repkey(pname, OBS=obsname, BIN=bin,
                                TAG=ftag + systag)  # image file name
                wname = "stack" + systag  # name in ROOT file
                stackinputs(tdir,
                            obs,
                            procs_,
                            group=groups,
                            save=pname_,
                            write=wname,
                            text=text_)

                # VARIATIONS
                if 'Down' in set:
                    systag_ = systag.replace(
                        'Down', '')  # e.g.'_TES' without 'Up' or 'Down' suffix
                    pname_ = repkey(pname,
                                    OBS=obsname,
                                    BIN=bin,
                                    TAG=ftag + "_$PROC" +
                                    systag)  # image file name
                    wname = "plot_$PROC" + systag  # name in ROOT file
                    comparevars(tdir,
                                obs,
                                procs,
                                systag_,
                                save=pname_,
                                write=wname,
                                text=text_)

        file.Close()