def makeOverlaidPlot():
    REFLIST = (('2Mu2J', (1000, 20, 2)), ('2Mu2J', (200, 50, 200)))
    key = 'Dim_deltaPhi_Matched'

    h = {
        REFLIST[0]: HISTS[REFLIST[0]][key].Clone(),
        REFLIST[1]: HISTS[REFLIST[1]][key].Clone(),
    }

    p = {}
    for ref in h:
        RT.addFlows(h[ref])
        if h[ref].GetNbinsX() > 100: h[ref].Rebin(10)
        p[ref] = Plotter.Plot(h[ref], '2#mu2j ({}, {}, {})'.format(*ref[1]),
                              'l', 'hist')

    fname = 'pdfs/{}{}_Overlaid.pdf'.format(key, CUTSTRING)

    canvas = Plotter.Canvas()
    canvas.addMainPlot(p[REFLIST[1]])
    canvas.addMainPlot(p[REFLIST[0]])
    canvas.makeLegend(lWidth=.25, pos='tl')
    #canvas.legend.moveLegend(Y=-.3)
    canvas.legend.resizeHeight()
    p[REFLIST[1]].SetLineColor(R.kBlue)
    p[REFLIST[0]].SetLineColor(R.kRed)
    RT.addBinWidth(canvas.firstPlot)

    pave1 = canvas.makeStatsBox(p[REFLIST[1]], color=R.kBlue)
    pave2 = canvas.makeStatsBox(p[REFLIST[0]], color=R.kRed)
    Plotter.MOVE_OBJECT(pave2, Y=-.22, NDC=False)
    canvas.cleanup(fname)
示例#2
0
def makeBinnedResPlot(MUON, fs, sp, quantity, q2):
    h = HistogramGetter.getHistogram(f, (fs, sp), '{M}_{Q}ResVS{Q2}'.format(M=MUON, Q=quantity, Q2=q2)).Clone()

    fname = 'pdfs/SRR_{}_{}_{}-Binned_{}HTo2XTo{}_{}.pdf'.format(MUON, quantity+'Res', q2, 'Trig-' if TRIGGER else '', fs, SPStr(sp))

    pretty, binranges, values, colors, colors2, legName = getBinningValues(q2)

    projections = {key:h.ProjectionY('_'+str(i), key[0], key[1]) for i,key in enumerate(binranges)}
    plots       = {key:Plotter.Plot(projections[key], legName.format(Q2=pretty, V1=values[key][0], V2=values[key][1]), 'l', 'hist') for key in binranges}

    canvas = Plotter.Canvas(lumi=SPLumiStr(fs, *sp))
    for key in binranges:
        RT.addFlows(plots[key])
        plots[key].Rebin(10)
        if plots[key].Integral() != 0:
            plots[key].Scale(1./plots[key].Integral())
        canvas.addMainPlot(plots[key])

    canvas.makeLegend(lWidth=.25, pos='tr')
    canvas.legend.moveLegend(X=-.08)
    canvas.legend.resizeHeight()
    canvas.setMaximum(recompute=True)

    for i, key in enumerate(binranges):
        plots[key].SetLineColor(colors[key])
        plots[key].setTitles(X=plots[key].GetXaxis().GetTitle(), Y='Normalized Counts')
        canvas.drawText('#color[{}]{{'.format(colors2[key]) + 'RMS = {:.4f}'.format(plots[key].GetStdDev()) + '}',
                        (canvas.legend.GetX1NDC()+.01, canvas.legend.GetY1NDC()-(i*0.04)-.04)
        )

    RT.addBinWidth(canvas.firstPlot)
    canvas.cleanup(fname)
def importHistogram(allhists,
                    resolution_variable,
                    includes=None,
                    excludes=None):
    imported_hists = []
    imported_d0hists = []
    for dat in allhists:
        resolution_hists = getHistNames(allhists,
                                        dat,
                                        *includes,
                                        exclude=excludes)

        for key in resolution_hists:
            if not all([d0str in key for d0str in ["__d0GT", "__d0LT"]]):
                continue

            h = allhists[dat][key].Clone()
            RT.addFlows(h)
            imported_hists.append(h)

            d0_histname = key.replace("__{}".format(resolution_variable),
                                      "__d0VAR")
            if d0_histname == key:
                raise Exception("Error parsing the name of the d0 histogram")

            d0_h = allhists[dat][d0_histname].Clone()
            RT.addFlows(d0_h)
            imported_d0hists.append(d0_h)

    return imported_hists, imported_d0hists
示例#4
0
def makePerSignalPlots(fs):
    for sp in SIGNALPOINTS:
        for key in HISTS[(fs, sp)]:
            h = HISTS[(fs, sp)][key]
            RT.addFlows(h)
            p = Plotter.Plot(h, '', 'p', 'hist')
            canvas = Plotter.Canvas(lumi=SPLumiStr(fs, *sp))
            canvas.addMainPlot(p)
            p.SetLineColor(R.kBlue)
            RT.addBinWidth(p)
            pave = canvas.makeStatsBox(p, color=R.kBlue)
            canvas.cleanup('pdfs/Gen_{}_{}HTo2XTo{}_{}.pdf'.format(
                key, 'Trig-' if TRIGGER else '', fs, SPStr(sp)))
def makePerSamplePlots():
    for ref in HISTS:
        for key in HISTS[ref]:
            if 'DenVS' in key: continue

            matches = re.match(r'(.*)EffVS(.*)', key)

            cut = matches.group(1)
            val = matches.group(2)

            if cut in Selections.CutLists['MuonCutList'] and val == 'Lxy':
                continue
            if cut in Selections.CutLists['DimuonCutList'] and val in ('pT',
                                                                       'eta',
                                                                       'd0'):
                continue

            if type(ref) == tuple:
                if ref[0] == '4Mu': name = 'HTo2XTo4Mu_'
                elif ref[0] == '2Mu2J': name = 'HTo2XTo2Mu2J_'
                name += SPStr(ref[1])
                if TRIGGER:
                    name = 'Trig-' + name
                lumi = SPLumiStr(ref[0], *ref[1])
                legName = HistogramGetter.PLOTCONFIG['HTo2XTo' +
                                                     ref[0]]['LATEX']
            else:
                name = ref
                lumi = HistogramGetter.PLOTCONFIG[ref]['LATEX']
                legName = HistogramGetter.PLOTCONFIG[ref]['LATEX']

            h = HISTS[ref][key].Clone()
            RT.addFlows(h)
            d = HISTS[ref][key.replace('Eff', 'Den')].Clone()
            RT.addFlows(d)
            g = R.TGraphAsymmErrors(h, d, 'cp')
            g.SetNameTitle(
                'g_' + key,
                ';' + h.GetXaxis().GetTitle() + ';' + h.GetYaxis().GetTitle())
            p = Plotter.Plot(g, '', 'pe', 'pe')

            canvas = Plotter.Canvas(lumi=lumi)
            canvas.addMainPlot(p)
            p.setColor(R.kBlue)
            canvas.firstPlot.SetMinimum(0.)
            canvas.firstPlot.SetMaximum(1.)

            fname = 'pdfs/NM1E_{}_{}.pdf'.format(key, name)
            canvas.cleanup(fname)
def makeGenRecoPlots():
    for ref in HISTS:
        if not type(ref) == tuple: continue
        if ref[0] == '4Mu':
            name = 'HTo2XTo4Mu_'
            latexFS = '4#mu'
        elif ref[0] == '2Mu2J':
            name = 'HTo2XTo2Mu2J_'
            latexFS = '2#mu2j'
        if TRIGGER:
            name = 'Trig-' + name
        name += SPStr(ref[1])
        lumi = SPLumiStr(ref[0], *ref[1])

        colors = {'Matched': R.kRed, 'Closest': R.kBlue}
        KEYS = ('Matched', 'Closest')

        for MUON in ('DSA', 'REF'):
            h, p = {}, {}
            for key in KEYS:
                h[key] = HISTS[ref]['{}_{}_{}'.format(MUON, 'deltaRGR',
                                                      key)].Clone()
                RT.addFlows(h[key])
                if h[key].GetNbinsX() > 100: h.Rebin(10)
                p[key] = Plotter.Plot(h[key], key, 'l', 'hist')
            fname = 'pdfs/{}{}_{}_{}_{}.pdf'.format(MUON, CUTSTRING,
                                                    'deltaRGR', 'Matched',
                                                    name)

            canvas = Plotter.Canvas(lumi=lumi)
            for key in KEYS:
                canvas.addMainPlot(p[key])
                p[key].SetLineColor(colors[key])

            canvas.makeLegend(lWidth=.25, pos='tr')
            canvas.legend.resizeHeight()
            canvas.setMaximum()
            RT.addBinWidth(canvas.firstPlot)

            LPOS = (canvas.legend.GetX1NDC() + .01,
                    canvas.legend.GetY1NDC() - .04)

            for i, key in enumerate(KEYS):
                canvas.drawText(text='#color[{}]{{n = {:d}}}'.format(
                    colors[key], int(p[key].GetEntries())),
                                pos=(LPOS[0], LPOS[1] - i * 0.04))

            canvas.cleanup(fname)
示例#7
0
def makeEffPlots(quantity, fs, SP=None):
    HKeys = {
        'Eff': '{}Eff',
        'Den': '{}Den',
    }
    for key in HKeys:
        HKeys[key] = HKeys[key].format(quantity)

    h = {}
    p = {}
    g = {}

    if SP is None:
        for i, sp in enumerate(SIGNALPOINTS):
            if i == 0:
                for key in HKeys:
                    h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
                    h[key].SetDirectory(0)
            else:
                for key in HKeys:
                    h[key].Add(HISTS[(fs, sp)][HKeys[key]])
    else:
        sp = SP
        for key in HKeys:
            h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
            h[key].SetDirectory(0)

    for key in HKeys:
        RT.addFlows(h[key])
        h[key].Rebin(10)

    g['Eff'] = R.TGraphAsymmErrors(h['Eff'], h['Den'], 'cp')
    g['Eff'].SetNameTitle(
        'g_Eff',
        ';' + h['Eff'].GetXaxis().GetTitle() + ';Vertex Fit Efficiency')
    p['Eff'] = Plotter.Plot(g['Eff'], '', 'elp', 'pe')

    canvas = Plotter.Canvas(lumi=fs if SP is None else SPLumiStr(fs, *SP))
    canvas.addMainPlot(p['Eff'])
    p['Eff'].setColor(R.kBlue)
    RT.addBinWidth(canvas.firstPlot)
    canvas.firstPlot.SetMinimum(0.)
    canvas.firstPlot.SetMaximum(1.)
    canvas.cleanup('pdfs/SVFE_{}Eff{}_{}HTo2XTo{}_{}.pdf'.format(
        quantity, CUTSTRING, 'Trig-' if TRIGGER else '', fs,
        'Global' if SP is None else SPStr(SP)))
示例#8
0
def getBackgroundHistograms(FILE, keylist, stack=True, addFlows=True, rebin=None, rebinVeto=None, extraScale=None):
    # allow passing a string or a list
    if type(keylist) == str:
        keylist = [keylist]

    # loop through the keys
    # if stack, make a THStack; otherwise, get started by using the first histogram
    # loop through the bg keys, addFlows if desired, scale, rebin if desired
    # if stack, Add
    # if not stack and this isn't the first, also Add
    # if not stack and this is the first, clone ("get started")
    # return dictionary of dictionary of histograms, and plot configs
    HISTS = {}
    PConfig = {}
    for key in keylist:
        HISTS[key] = {}
        PConfig[key] = {'stack':('', '', 'hist')}
        if stack:
            HISTS[key]['stack'] = R.THStack('hStack', '')
        for ref in BGORDER:
            HISTS[key][ref] = getHistogram(FILE, ref, key).Clone()
            if addFlows:
                RT.addFlows(HISTS[key][ref])
            HISTS[key][ref].Scale(PLOTCONFIG[ref]['WEIGHT'])
            if extraScale is not None:
                HISTS[key][ref].Scale(extraScale)
            if rebin is not None and (rebinVeto is None or (rebinVeto is not None and not rebinVeto(key))):
                is2D = 'TH2' in str(HISTS[key][ref].__class__)
                if is2D:
                    if not hasattr(rebin, '__iter__'):
                        print '[HISTOGRAMGETTER ERROR]: For 2D plots, "rebin" must be a list of 2 rebin values'
                        exit()
                    HISTS[key][ref].Rebin2D(*rebin)
                else:
                    HISTS[key][ref].Rebin(rebin)
            PConfig[key][ref] = (PLOTCONFIG[ref]['LATEX'], 'f', 'hist')
            if not stack and ref == BGORDER[0]:
                HISTS[key]['stack'] = HISTS[key][ref].Clone()
                continue
            HISTS[key]['stack'].Add(HISTS[key][ref])

    return HISTS, PConfig
def makePerSamplePlots():
    for ref in HISTS:
        if not type(ref) == tuple: continue
        for key in HISTS[ref]:
            if 'deltaRGR' in key: continue
            if 'VS' in key: continue
            if type(ref) == tuple:
                if ref[0] == '4Mu':
                    name = 'HTo2XTo4Mu_'
                    latexFS = '4#mu'
                elif ref[0] == '2Mu2J':
                    name = 'HTo2XTo2Mu2J_'
                    latexFS = '2#mu2j'
                if TRIGGER:
                    name = 'Trig-' + name
                name += SPStr(ref[1])
                lumi = SPLumiStr(ref[0], *ref[1])
                legName = HistogramGetter.PLOTCONFIG['HTo2XTo' +
                                                     ref[0]]['LATEX']
            else:
                if '_Matched' in key: continue
                name = ref
                lumi = HistogramGetter.PLOTCONFIG[ref]['LATEX']
                legName = HistogramGetter.PLOTCONFIG[ref]['LATEX']

            h = HISTS[ref][key].Clone()
            RT.addFlows(h)
            if h.GetNbinsX() > 100: h.Rebin(10)
            p = Plotter.Plot(h, legName, 'l', 'hist')
            fname = 'pdfs/{}{}_{}.pdf'.format(key, CUTSTRING, name)

            canvas = Plotter.Canvas(lumi=lumi)
            canvas.addMainPlot(p)
            canvas.makeLegend(lWidth=.25, pos='tr')
            canvas.legend.moveLegend(Y=-.3)
            canvas.legend.resizeHeight()
            p.SetLineColor(R.kBlue)
            RT.addBinWidth(p)

            pave = canvas.makeStatsBox(p, color=R.kBlue)
            canvas.cleanup(fname)
def makePerSamplePlots():
    for ref in HISTS:
        for key in HISTS[ref]:
            if type(ref) == tuple:
                if ref[0] == '4Mu': name = 'HTo2XTo4Mu_'
                elif ref[0] == '2Mu2J': name = 'HTo2XTo2Mu2J_'
                name += SPStr(ref[1])
                if TRIGGER:
                    name = 'Trig-' + name
                lumi = SPLumiStr(ref[0], *ref[1])
                legName = HistogramGetter.PLOTCONFIG['HTo2XTo' +
                                                     ref[0]]['LATEX']
            else:
                name = ref
                lumi = HistogramGetter.PLOTCONFIG[ref]['LATEX']
                legName = HistogramGetter.PLOTCONFIG[ref]['LATEX']

            h = HISTS[ref][key].Clone()
            RT.addFlows(h)
            p = Plotter.Plot(h, legName, 'l', 'hist')
            fname = 'pdfs/NM1_{}_{}.pdf'.format(key, name)
            canvas = Plotter.Canvas(lumi=lumi)
            canvas.lumi += ' : |#Delta#Phi| ' + ('<' if '_Less' in key else
                                                 '>') + ' #pi/2'
            canvas.addMainPlot(p)
            canvas.makeLegend(lWidth=.25, pos='tr')
            canvas.legend.moveLegend(Y=-.3)
            canvas.legend.resizeHeight()
            p.SetLineColor(R.kBlue)
            RT.addBinWidth(p)

            cutKey = key.replace('_Less', '').replace('_More', '')
            cutVal = Selections.CUTS[cutKey].val

            l = R.TLine(cutVal, p.GetMinimum(), cutVal, p.GetMaximum() * 1.05)
            l.SetLineStyle(2)
            l.SetLineWidth(2)
            l.Draw()

            canvas.cleanup(fname)
示例#11
0
def makeBinnedResPlotBinwise(MUONS, outputTag, quantity, q2, fs, sp):
    defaultColorOrder = (R.kRed, R.kBlue, R.kGreen, R.kMagenta)
    h = {}
    for MUON in MUONS:
        h[MUON] = HistogramGetter.getHistogram(f, (fs, sp), '{M}_{Q}ResVS{Q2}'.format(M=MUON, Q=quantity, Q2=q2)).Clone()

    # leaving space for the bin number
    fname = 'pdfs/SRR_{}_{}_{}-Binned-Bin-{{}}_{}HTo2XTo{}_{}.pdf'.format(outputTag, quantity+'Res', q2, 'Trig-' if TRIGGER else '', fs, SPStr(sp))

    pretty, binranges, values, colors, colors2, legName = getBinningValues(q2)

    for i, key in enumerate(binranges):
        canvas = Plotter.Canvas(lumi=SPLumiStr(fs, *sp))
        projections, plots = {}, {}
        for j, MUON in enumerate(MUONS):
            projections[MUON] = h[MUON].ProjectionY('_'+str(i)+'_'+str(j), key[0], key[1])
            plots[MUON]       = Plotter.Plot(projections[MUON], MUON, 'l', 'hist')
            RT.addFlows(plots[MUON])
            plots[MUON].Rebin(10)
            if plots[MUON].Integral() != 0:
                plots[MUON].Scale(1./plots[MUON].Integral())
            plots[MUON].SetLineColor(defaultColorOrder[j])

            canvas.addMainPlot(plots[MUON])

        canvas.makeLegend(lWidth=.25, pos='tr')
        canvas.legend.resizeHeight()
        canvas.setMaximum(recompute=True)

        canvas.drawText(legName.format(Q2=pretty, V1=values[key][0], V2=values[key][1]), (canvas.legend.GetX1NDC()+.01, canvas.legend.GetY1NDC()-.04))

        for j, MUON in enumerate(MUONS):
            plots[MUON].SetLineColor(defaultColorOrder[j])
            plots[MUON].setTitles(X=plots[MUON].GetXaxis().GetTitle(), Y='Normalized Counts')
            canvas.drawText('#color[{}]{{'.format(defaultColorOrder[j]) + 'RMS = {:.4f}'.format(plots[MUON].GetStdDev()) + '}',
                (canvas.legend.GetX1NDC()+.01, canvas.legend.GetY1NDC()-(j*0.04)-.08)
            )

        RT.addBinWidth(canvas.firstPlot)
        canvas.cleanup(fname.format(i+1))
示例#12
0
def getDataHistograms(FILE, keylist, addFlows=True, rebin=None, rebinVeto=None):
    # allow passing a string or a list
    if type(keylist) == str:
        keylist = [keylist]

    DataKeys = ['DoubleMuonRun2016{}-07Aug17{}'.format(era, '' if era != 'B' else '-v2') for era in ('B', 'C', 'D', 'E', 'F', 'G', 'H')]

    # loop through the keys
    # if stack, make a THStack; otherwise, get started by using the first histogram
    # loop through the bg keys, addFlows if desired, scale, rebin if desired
    # if stack, Add
    # if not stack and this isn't the first, also Add
    # if not stack and this is the first, clone ("get started")
    # return dictionary of dictionary of histograms, and plot configs
    HISTS = {}
    PConfig = {}
    for key in keylist:
        HISTS[key] = {}
        PConfig[key] = {'data':('DoubleMuon2016', 'pe', 'pe')}
        for ref in DataKeys:
            HISTS[key][ref] = getHistogram(FILE, ref, key).Clone()
            if addFlows:
                RT.addFlows(HISTS[key][ref])
            if rebin is not None and (rebinVeto is None or (rebinVeto is not None and not rebinVeto(key))):
                is2D = 'TH2' in str(HISTS[key][ref].__class__)
                if is2D:
                    if not hasattr(rebin, '__iter__'):
                        print '[HISTOGRAMGETTER ERROR]: For 2D plots, "rebin" must be a list of 2 rebin values'
                        exit()
                    HISTS[key][ref].Rebin2D(*rebin)
                else:
                    HISTS[key][ref].Rebin(rebin)
            if ref == DataKeys[0]:
                HISTS[key]['data'] = HISTS[key][ref].Clone()
                continue
            HISTS[key]['data'].Add(HISTS[key][ref])

    return HISTS, PConfig
示例#13
0
            weight = HG.PLOTCONFIG[cols[0]]['WEIGHT'] * int(cols[4]) * .100033
            key = cols[0]
        else: # data
            weight = 1.
            key = 'data'

        for val in (cols[-2], cols[-1]):
            if val == 'inf':
                hists[key].Fill(100., weight)
            else:
                hists[key].Fill(float(val)**(2. if DOSQUARED else 1.), weight)

stack = R.THStack('hstack', '')
p = {}
for key in l:
    RT.addFlows(hists[key])
    if key == 'data': continue
    stack.Add(hists[key])
    p[key] = Plotter.Plot(hists[key], HG.PLOTCONFIG[key]['LATEX'], 'f', 'hist')
    p[key].setColor(HG.PLOTCONFIG[key]['COLOR'], which='LF')

p['stack'] = Plotter.Plot(stack, '', '', 'hist')
p['data'] = Plotter.Plot(hists['data'], 'DoubleMuon2016', 'lp', 'pe')

c = Plotter.Canvas(logy=True)
c.addMainPlot(p['stack'])
c.addMainPlot(p['data'])
c.makeLegend(lWidth=.27, pos='tr', autoOrder=False, fontscale=0.8)
for ref in reversed(l):
    c.addLegendEntry(p[ref])
c.legend.resizeHeight()
示例#14
0
def importHistograms(DISTRIBUTION_SPECS):
    """
    Read and add specified histograms from one or many files.

    Extracts histograms from one or many ROOT files (defined via the argument
    'DISTRIBUTION_SPECS') and adds them to the given HistSpecs objects.

    Parameters
    ----------
    DISTRIBUTION_SPECS : HistSpecs object
        An instance of the HistSpecs class, which defines all the relevant histogram
        properties

    """

    # perform some basic sanity checks
    for el in DISTRIBUTION_SPECS:
        filepath = el.getAttribute("filepath")
        histname_identifier = el.getAttribute("histname_identifier")
        histname_exclude = el.getAttribute("histname_exclude")

        types = ((filepath, str), (histname_identifier, str),
                 (histname_exclude, list))
        for o, t in types:
            if not isinstance(o, t):
                raise Exception(
                    "Invalid type of {}: should be {}, but is {}".format(
                        o, t, type(o)))

        if not os.path.exists(filepath):
            raise Exception("No such file: {}".format(filepath))

    # dictionary structure for collecting the relevant distributions
    hists = {}

    cnt_files = 1
    for el in DISTRIBUTION_SPECS:
        filepath = el.getAttribute("filepath")
        histname_identifier = el.getAttribute("histname_identifier")
        histname_exclude = el.getAttribute("histname_exclude")

        print("[{}/{}] Reading file {}...".format(cnt_files,
                                                  len(DISTRIBUTION_SPECS),
                                                  filepath))

        f_allhists = HistogramGetter.getHistograms(filepath)

        histogram = None

        for dataset in f_allhists:
            selected_hists_names = getHistNames(f_allhists,
                                                dataset,
                                                histname_identifier,
                                                exclude=histname_exclude)
            print("hist names: {}".format(selected_hists_names))

            if len(selected_hists_names) > 1:
                raise Exception(
                    "Ambiguous histogram identifier: {} would select the following {} histograms: {}"
                    .format(histname_identifier, len(selected_hists_names),
                            '\n'.join(selected_hists_names)))

            for key in selected_hists_names:
                if histogram is None:
                    histogram = f_allhists[dataset][key].Clone()
                else:
                    histogram.Add(f_allhists[dataset][key])

        if histogram:
            print("\tImported histogram {}".format(histogram.GetName()))
        else:
            print("\tNo histograms found.")

        # prepare the histogram
        RT.addFlows(histogram)

        if el.getAttribute("histogram") is not None:
            print(
                "Warning: Histogram already exists in the HistSpecs object and will be overwritten"
            )

        # add the actual histrogram to the corresponding HistSpecs object
        el.setAttribute("histogram", histogram)

        cnt_files += 1
        del f_allhists
示例#15
0
def makeResPlots(metric, quantity):
    PRETTY = {
        'pTRes_hits_less': {
            'mnice': 'p_{T} res.',
            'qnice': 'N(hits)',
            'leg': 'N(hits) #leq 12',
            'col': R.kRed
        },
        'pTRes_hits_more': {
            'mnice': 'p_{T} res.',
            'qnice': 'N(hits)',
            'leg': 'N(hits) > 12',
            'col': R.kBlue
        },
        'pTRes_fpte_less': {
            'mnice': 'p_{T} res.',
            'qnice': '#sigma_{p_{T}}/p_{T}',
            'leg': '#sigma_{p_{T}}/p_{T} < 1',
            'col': R.kBlue
        },
        'pTRes_fpte_more': {
            'mnice': 'p_{T} res.',
            'qnice': '#sigma_{p_{T}}/p_{T}',
            'leg': '#sigma_{p_{T}}/p_{T} #geq 1',
            'col': R.kRed
        },
        'qdiff_hits_less': {
            'mnice': 'charge diff.',
            'qnice': 'N(hits)',
            'leg': 'N(hits) #leq 12',
            'col': R.kRed
        },
        'qdiff_hits_more': {
            'mnice': 'charge diff.',
            'qnice': 'N(hits)',
            'leg': 'N(hits) > 12',
            'col': R.kBlue
        },
        'qdiff_fpte_less': {
            'mnice': 'charge diff.',
            'qnice': '#sigma_{p_{T}}/p_{T}',
            'leg': '#sigma_{p_{T}}/p_{T} < 1',
            'col': R.kBlue
        },
        'qdiff_fpte_more': {
            'mnice': 'charge diff.',
            'qnice': '#sigma_{p_{T}}/p_{T}',
            'leg': '#sigma_{p_{T}}/p_{T} #geq 1',
            'col': R.kRed
        },
    }
    witches = ('less', 'more')
    hkeys = ['{}_{}_{}'.format(metric, quantity, which) for which in witches]

    HISTS = HG.getAddedSignalHistograms(FILES['Signal'], '2Mu2J', hkeys)

    PLOTS = {}
    for key in hkeys:
        HISTS[key].Scale(1. /
                         HISTS[key].Integral(0, HISTS[key].GetNbinsX() + 1))
        RT.addFlows(HISTS[key])
        PLOTS[key] = Plotter.Plot(HISTS[key], PRETTY[key]['leg'], 'l', 'hist')

    canvas = Plotter.Canvas(lumi='{} by {}'.format(PRETTY[hkeys[0]]['mnice'],
                                                   PRETTY[hkeys[0]]['qnice']))

    for key in hkeys:
        canvas.addMainPlot(PLOTS[key])
        PLOTS[key].setColor(PRETTY[key]['col'], which='L')

    canvas.firstPlot.SetMinimum(0.)
    canvas.firstPlot.SetMaximum(0.08 if metric == 'pTRes' else 1.)

    canvas.firstPlot.setTitles(Y='Density')
    if 'qdiff' in hkeys[0]:
        canvas.firstPlot.SetNdivisions(3)

    canvas.makeLegend(lWidth=0.27, pos='tr')

    RT.addBinWidth(canvas.firstPlot)
    canvas.cleanup('Res_Sig_{}_{}.pdf'.format(metric, quantity))
示例#16
0
    def makeEffPlots(quantity, fs, SP=None):
        range_limits = {
                'pT': [0., 300.],
                'eta': None,
                'phi': None,
                'd0': None,
                'Lxy': [0., (500. if SP is None else \
                        SAMPLE_SPECS[fs]['{}_{}_{}'.format(*SP)]['xmax'])],
                'deltaR': None,
                'mass': None,
                'cosAlpha': None,
                'dimuonPTOverM': [0, 10],
                'XBeta': None,
        }

        HKeys = {
            'GEN_Eff'       : 'GEN_{}Num'      ,
            'GEN_Den'       : 'GEN_{}Den'      ,
            'DSA_Eff'       : 'DSA_{}Num'      ,
            'DSA_Den'       : 'DSA_{}Den'      ,
            'RSA_Eff'       : 'RSA_{}Num'      ,
            'RSA_Den'       : 'RSA_{}Den'      ,
        }
        for key in HKeys:
            HKeys[key] = HKeys[key].format(quantity, 'HTo2XTo'+fs)

        h = {}
        p = {}
        g = {}
        hm = {}

        if SP is None:
            for i, sp in enumerate(SIGNALPOINTS):
                if i == 0:
                    for key in HKeys:
                        h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
                        h[key].SetDirectory(0)
                else:
                    for key in HKeys:
                        h[key].Add(HISTS[(fs, sp)][HKeys[key]])

        else:
            sp = SP
            for key in HKeys:
                h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
                h[key].SetDirectory(0)

        for key in HKeys:
            RT.addFlows(h[key])
            nConcatBins = 20 if SP is None else \
                    SAMPLE_SPECS[fs]['{}_{}_{}'.format(*SP)]['rebin']
            h[key].Rebin(nConcatBins)
            # h[key].Rebin(30)

        NumDens = (
            ('GEN_Eff'      , 'GEN_Den'          , 'GEN'       , R.kGreen   ),
            ('DSA_Eff'      , 'DSA_Den'          , 'DSA'       , R.kBlue    ),
            ('RSA_Eff'      , 'RSA_Den'          , 'RSA'       , R.kRed     ),
        )

        for num, den, leg, col in NumDens:
            g[num] = R.TGraphAsymmErrors(h[num], h[den], 'cp')
            g[num].SetNameTitle('g_'+num, ';'+h[num].GetXaxis().GetTitle()+'; Trigger Efficiency')
            # g[num].GetXaxis().SetRangeUser(0., 30.)
            if range_limits[quantity] is not None:
                g[num].GetXaxis().SetLimits(
                        range_limits[quantity][0],
                        range_limits[quantity][1])

            p[num] = Plotter.Plot(g[num], leg, 'elp', 'pe')

            h[num].Sumw2()
            h[den].Sumw2()

            ratio_hist = R.TEfficiency(h[num], h[den])
            eff_sum_num = 0
            eff_sum_den = 0
            for binx in range(1,h[num].GetXaxis().GetNbins()+2):
                # if h[num].GetBinLowEdge(binx) > 250: continue
                glob_bin = ratio_hist.GetGlobalBin(binx)
                efferror = max(ratio_hist.GetEfficiencyErrorLow(glob_bin),
                        ratio_hist.GetEfficiencyErrorUp(glob_bin))
                if efferror != 0:
                    eff_sum_num += ratio_hist.GetEfficiency(glob_bin) / \
                            (efferror*efferror)
                    if ratio_hist.GetEfficiency(glob_bin) != 0:
                        eff_sum_den += 1/(efferror*efferror)
            if eff_sum_den != 0:
                hm[num] = eff_sum_num / eff_sum_den


        FIRST  = (0, 3)
        # SECOND = (3, 5)
        CHARGE = ''
        for SECTION in (FIRST,):
            fraction_str = '' if SP is None else '[{}%, {}%]'.format(
                    round(SAMPLE_SPECS[fs]['{}_{}_{}'.format(*SP)]['fractions'][0], 1),
                    round(SAMPLE_SPECS[fs]['{}_{}_{}'.format(*SP)]['fractions'][1], 1))
            canvas = Plotter.Canvas(lumi = fs if SP is None else \
                    '{} ({} GeV, {} GeV, {} mm) ' \
                    '#scale[0.7]{{{fraction_str}}}'.format(
                        fs, *SP, fraction_str=fraction_str))
            for i in range(SECTION[0], SECTION[1]):
                key = NumDens[i][0]
                col = NumDens[i][3]
                canvas.addMainPlot(p[key])
                p[key].SetMarkerColor(col)
                p[key].SetLineColor(col)

                # if quantity in ['Lxy','pT']:
                #     axis_min = p[key].GetXaxis().GetBinLowEdge(1)
                #     axis_max = p[key].GetXaxis().GetBinLowEdge(p[key].GetXaxis().GetNbins()+1)
                #     hline = R.TLine(axis_min, hm[key], range_limits[quantity][1], hm[key])
                #     R.SetOwnership(hline, 0)
                #     hline.SetLineColor(col)
                #     hline.Draw()
                

            canvas.makeLegend(pos='tr')
            canvas.legend.moveLegend(X=-0.18)
            canvas.legend.resizeHeight()
            canvas.firstPlot.SetMinimum(0.)
            canvas.firstPlot.SetMaximum(1.)
            RT.addBinWidth(canvas.firstPlot)
            if quantity == 'pT':
                vline = R.TLine(28.,0.,28.,1.)  # draw vertical line at 28 GeV
                R.SetOwnership(vline, 0)
                vline.SetLineColor(15)
                vline.Draw()

            canvas.cleanup(OUTPUT_PATH + FILENAME_OUT.format('STE', LXYMIN, LXYMAX, quantity, fs, 'Global' if SP is None else SPStr(SP)))
示例#17
0
    def makeSimplePlots(quantity, fs, SP=None, normalize=False):
        range_limits = {
                'pT': [0., 300.],
                'eta': None,
                'phi': None,
                'd0': None,
                'Lxy': [0., (500. if SP is None else \
                        SAMPLE_SPECS[fs]['{}_{}_{}'.format(*SP)]['xmax'])],
                'deltaR': None,
                'mass': None,
                'cosAlpha': None,
                'dimuonPTOverM': [0, 10],
                'XBeta': None,
        }

        HKeys = {
            'GEN_Den' : 'GEN_{}Den',
            'DSA_Den' : 'DSA_{}Den',
            'RSA_Den' : 'RSA_{}Den',
        }
        for key in HKeys:
            HKeys[key] = HKeys[key].format(quantity, 'HTo2XTo'+fs)

        h = {}
        p = {}

        if SP is None:
            for i, sp in enumerate(SIGNALPOINTS):
                if i == 0:
                    for key in HKeys:
                        h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
                        h[key].Sumw2()
                        h[key].SetDirectory(0)
                else:
                    for key in HKeys:
                        h[key].Sumw2()
                        h[key].Add(HISTS[(fs, sp)][HKeys[key]])

        else:
            for key in HKeys:
                h[key] = HISTS[(fs, SP)][HKeys[key]].Clone()
                h[key].Sumw2()
                if normalize is True and h[key].Integral() != 0:
                    h[key].Scale(1/h[key].Integral())
                h[key].SetDirectory(0)

        for key in HKeys:
            RT.addFlows(h[key])
            nConcatBins = 20 if SP is None else \
                    SAMPLE_SPECS[fs]['{}_{}_{}'.format(*SP)]['rebin']
            h[key].Rebin(nConcatBins)
        
        if quantity == 'deltaR':
            ratio_cut = 0.5
            hist_ratios = {}
            for key in HKeys:
                num_before_cut = 0
                num_after_cut = 0
                for i in range(h[key].GetNbinsX()+1):
                    if h[key].GetXaxis().GetBinCenter(i) < ratio_cut:
                        num_before_cut += h[key].GetBinContent(i)
                    else:
                        num_after_cut += h[key].GetBinContent(i)

                if num_before_cut+num_after_cut != 0:
                    hist_ratios[key] = 1.0*num_before_cut/(num_before_cut+num_after_cut)
                else:
                    hist_ratios[key] = -1

        HistSpecs = (
            ('GEN_Den', 'GEN', R.kGreen, 'Yield [a.u.]'),
            ('DSA_Den', 'DSA', R.kBlue, 'Yield [a.u.]'),
            ('RSA_Den', 'RSA', R.kRed, 'Yield [a.u.]'),
        )

        for key, leg, col, yTitle in HistSpecs:
            if range_limits[quantity] is not None:
                h[key].GetXaxis().SetRangeUser(
                        range_limits[quantity][0],
                        range_limits[quantity][1])
            
            h[key].SetNameTitle('h_'+key,
                    ';'+h[key].GetXaxis().GetTitle() + '; ' + \
                    ('Normalized ' if normalize is True else '') + yTitle)
            # leg += (': yield(#Delta R<0.5) #times 100 / (total yield) = {}'.format(
            #     round(hist_ratios[key]*100,2)) if quantity == 'deltaR' else '')
            p[key] = Plotter.Plot(h[key], leg, '', 'hist e1 x0')
            
        FIRST = (0, 3)
        CHARGE = ''
        for SECTION in (FIRST,):
            fraction_str = '' if SP is None else '[{}%, {}%]'.format(
                    round(SAMPLE_SPECS[fs]['{}_{}_{}'.format(*SP)]['fractions'][0], 1),
                    round(SAMPLE_SPECS[fs]['{}_{}_{}'.format(*SP)]['fractions'][1], 1))

            canvas = Plotter.Canvas(lumi = fs if SP is None else \
                    '{} ({} GeV, {} GeV, {} mm) ' \
                    '#scale[0.7]{{{fraction_str}}}'.format(
                        fs, *SP, fraction_str=fraction_str))

            for i in range(SECTION[0], SECTION[1]):
                key = HistSpecs[i][0]
                col = HistSpecs[i][2]
                yTitle = HistSpecs[i][3]
                canvas.addMainPlot(p[key])
                p[key].SetMarkerColor(col)
                p[key].SetLineColor(col)
                # p[key].firstPlot.SetYTitle(yTitle)

            canvas.makeLegend(pos='tl')
            canvas.legend.moveLegend(X=0.15)
            canvas.legend.resizeHeight()
            RT.addBinWidth(canvas.firstPlot)

            canvas.cleanup(OUTPUT_PATH + FILENAME_OUT.format('STD', LXYMIN, LXYMAX, quantity, fs, 'Global' if SP is None else SPStr(SP)))
def makeStackPlots(DataMC=False, logy=False):
    BGORDER = ('WJets', 'WW', 'WZ', 'ZZ', 'tW', 'tbarW', 'ttbar', 'DY10to50',
               'DY50toInf')
    for hkey in HISTS['DY50toInf']:
        if 'DenVS' in hkey: continue

        matches = re.match(r'(.*)EffVS(.*)', hkey)

        cut = matches.group(1)
        val = matches.group(2)

        if cut in Selections.CutLists['MuonCutList'] and val == 'Lxy': continue
        if cut in Selections.CutLists['DimuonCutList'] and val in ('pT', 'eta',
                                                                   'd0'):
            continue

        h = {
            #           'Data'       : HISTS['DoubleMuonRun2016D-07Aug17'][hkey].Clone(),
            #           'Signal'     : HISTS[('4Mu', (125, 20, 13))      ][hkey].Clone(),
            'BG': R.THStack('hBG', '')
        }

        dkey = hkey.replace('EffVS', 'DenVS')
        d = {
            #           'Data'       : HISTS['DoubleMuonRun2016D-07Aug17'][dkey].Clone(),
            #           'Signal'     : HISTS[('4Mu', (125, 20, 13))      ][dkey].Clone(),
            'BG': R.THStack('hBGD', '')
        }

        PConfig = {
            #           'Data'       : ('DoubleMuon2016D'              , 'pe', 'pe'  ),
            #           'Signal'     : ('H#rightarrow2X#rightarrow4#mu', 'l' , 'hist'),
            'BG': ('', '', 'hist'),
        }

        PC = HistogramGetter.PLOTCONFIG

        for key in BGORDER:
            PConfig[key] = (PC[key]['LATEX'], 'f', 'hist')
            for DICT, KEY in ((h, hkey), (d, dkey)):
                DICT[key] = HISTS[key][KEY].Clone()
                RT.addFlows(DICT[key])
                if DICT[key].GetNbinsX() > 100: DICT[key].Rebin(10)
                DICT[key].Scale(PC[key]['WEIGHT'])
                DICT['BG'].Add(DICT[key])

        g = R.TGraphAsymmErrors(h['BG'].GetStack().Last(),
                                d['BG'].GetStack().Last(), 'cp')
        g.SetNameTitle(
            'g_' + hkey, ';' + h['DY50toInf'].GetXaxis().GetTitle() + ';' +
            h['DY50toInf'].GetYaxis().GetTitle())
        p = Plotter.Plot(g, '', 'pe', 'pe')

        fname = 'pdfs/NM1E_{}_Stack{}.pdf'.format(hkey, '-Log' if logy else '')

        canvas = Plotter.Canvas(ratioFactor=0. if not DataMC else 1. / 3.,
                                cHeight=600 if not DataMC else 800,
                                logy=logy)
        canvas.addMainPlot(p)
        #       canvas.addMainPlot(p['Data'])
        #       canvas.addMainPlot(p['Signal'])

        p.setColor(R.kBlue)
        canvas.firstPlot.SetMinimum(0.)
        canvas.firstPlot.SetMaximum(1.)
        #canvas.firstPlot.SetMaximum(1.e-4)

        #       if DataMC:
        #           canvas.makeRatioPlot(p['Data'].plot, p['BG'].plot.GetStack().Last())

        #       p['Signal'    ].SetLineStyle(2)
        #       p['Signal'    ].SetLineColor(R.kRed)

        canvas.cleanup(fname)
示例#19
0
def makeEffPlots(quantity, fs, SP=None):
    HKeys = {
        'DSA_Eff': 'DSA_{}Eff',
        'RSA_Eff': 'RSA_{}Eff',
        'REF_Eff': 'REF_{}Eff',
        'REF_Den': 'REF_{}Den',
        'Den': '{}Den',
        #       'Extra'         : '{}Extra'        ,
        'DSA_ChargeEff': 'DSA_{}ChargeEff',
        'RSA_ChargeEff': 'RSA_{}ChargeEff',
        'REF_ChargeEff': 'REF_{}ChargeEff',
        'DSA_ChargeDen': 'DSA_{}ChargeDen',
        'RSA_ChargeDen': 'RSA_{}ChargeDen',
        'REF_ChargeDen': 'REF_{}ChargeDen',
    }
    for key in HKeys:
        HKeys[key] = HKeys[key].format(quantity)

    h = {}
    p = {}
    g = {}

    if SP is None:
        for i, sp in enumerate(SIGNALPOINTS):
            if i == 0:
                for key in HKeys:
                    h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
                    h[key].SetDirectory(0)
            else:
                for key in HKeys:
                    h[key].Add(HISTS[(fs, sp)][HKeys[key]])
    else:
        sp = SP
        for key in HKeys:
            h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
            h[key].SetDirectory(0)

    for key in HKeys:
        RT.addFlows(h[key])
        if quantity != 'dR':
            h[key].Rebin(10)
        else:
            h[key].Rebin(5)

# Extra is commented out, same with FIRST SECOND
# so they don't appear on SRE plots by default now

    NumDens = (
        ('DSA_Eff', 'Den', 'DSA', R.kBlue),
        ('RSA_Eff', 'Den', 'RSA', R.kRed),
        ('REF_Eff', 'REF_Den', 'REF', R.kGreen),
        #       ('Extra'        , 'Den'          , 'Extra'     , R.kMagenta),
        ('DSA_ChargeEff', 'DSA_ChargeDen', 'DSA:Charge', R.kBlue),
        ('RSA_ChargeEff', 'RSA_ChargeDen', 'RSA:Charge', R.kRed),
        ('REF_ChargeEff', 'REF_ChargeDen', 'REF:Charge', R.kGreen),
    )

    for num, den, leg, col in NumDens:
        g[num] = R.TGraphAsymmErrors(h[num], h[den], 'cp')
        g[num].SetNameTitle(
            'g_' + num,
            ';' + h[num].GetXaxis().GetTitle() + ';Reconstruction Efficiency')
        p[num] = Plotter.Plot(g[num], leg, 'elp', 'pe')


#   FIRST  = (0, 3)
#   SECOND = (3, 5)
#   FIRST  = (0, 2)
#   SECOND = (2, 4)
    FIRST = (0, 3)
    SECOND = (3, 6)
    CHARGE = ''
    for SECTION in (FIRST, SECOND):
        canvas = Plotter.Canvas(lumi=fs if SP is None else SPLumiStr(fs, *SP))
        for i in range(SECTION[0], SECTION[1]):
            key = NumDens[i][0]
            col = NumDens[i][3]
            canvas.addMainPlot(p[key])
            p[key].setColor(col)
        # aesthetic change
        if quantity == 'Lxy' or (quantity == 'd0' and CHARGE == ''):
            canvas.makeLegend(pos='bl')
        else:
            canvas.makeLegend(pos='br')
            canvas.legend.moveLegend(Y=0.25)
            canvas.legend.moveLegend(X=-.1)
        canvas.legend.resizeHeight()
        canvas.firstPlot.SetMinimum(0.)
        canvas.firstPlot.SetMaximum(1.)
        #RT.addBinWidth(canvas.firstPlot)
        # aesthetic change
        if quantity == 'dR':
            canvas.firstPlot.GetXaxis().SetRangeUser(0., 1.)
        elif quantity == 'pT':
            canvas.firstPlot.GetXaxis().SetRangeUser(0., 800.)
        canvas.cleanup('pdfs/SRE_{}{}Eff_{}HTo2XTo{}_{}.pdf'.format(
            quantity, CHARGE, 'Trig-' if TRIGGER else '', fs,
            'Global' if SP is None else SPStr(SP)))
        CHARGE = 'Charge'
def makeSimpleComparisonPlots(hist_patterns_and_excludes):
    p = {
        f: {
            "appearance": app,
            "descr": d,
            "plots": {}
        }
        for app, f, d in file_specs
    }
    h_d0 = {f: {}
            for __, f, __ in file_specs
            }  # stores d0 histograms for a given key
    h_eta = {f: {}
             for __, f, __ in file_specs
             }  # stores eta histograms for a given key
    h_pT = {f: {}
            for __, f, __ in file_specs
            }  # stores pT histograms for a given key
    p_norm = {
        f: {
            "appearance": app,
            "descr": d,
            "plots": {}
        }
        for app, f, d in file_specs
    }

    rebinning_exceptions = ()

    custom_xranges = {
        "pTresVAR": [-1, 5],
        "d0VAR": [0, 400],
    }

    hists = collectHistograms(file_specs, hist_patterns_and_excludes)

    # prepare the histograms
    for appearance, f, f_descr in file_specs:
        for key in hists[f]["hists"]:
            RT.addFlows(hists[f]["hists"][key])

            if not any([e in key for e in rebinning_exceptions]):
                if hists[f]["hists"][key].GetNbinsX() >= 1000:
                    hists[f]["hists"][key].Rebin(5)
                elif hists[f]["hists"][key].GetNbinsX() >= 100:
                    hists[f]["hists"][key].Rebin(2)
                else:
                    pass

            legName = f_descr

            p[f]["plots"][key] = Plotter.Plot(hists[f]["hists"][key], legName,
                                              "l", "hist")

            # also store the d0 histogram corresponding to the current histogram,
            # if the corresponding d0 histogram is available
            if key not in h_d0[f]:
                d0_key = re.sub(r"__(.+)VAR", "__d0VAR", key)
                if d0_key in hists[f]["hists"]:
                    h_d0[f][key] = hists[f]["hists"][d0_key]

            # store the eta histogram corresponding to the current histogram
            if key not in h_eta[f]:
                eta_key = re.sub(r"__(.+)VAR", "__etaVAR", key)
                if eta_key in hists[f]["hists"]:
                    h_eta[f][key] = hists[f]["hists"][eta_key]

            # store the pT histogram corresponding to the current histogram
            if key not in h_pT[f]:
                pT_key = re.sub(r"__(.+)VAR", "__pTVAR", key)
                if pT_key in hists[f]["hists"]:
                    h_pT[f][key] = hists[f]["hists"][pT_key]

            h_norm = hists[f]["hists"][key].Clone()
            if h_norm.Integral() > 0:
                h_norm.Scale(1.0 / h_norm.Integral())
            else:
                pass

            p_norm[f]["plots"][key] = Plotter.Plot(h_norm, legName, "l",
                                                   "hist")

    for plots, suffix in ((p_norm, "_norm"), (p, "")):
        for is_logy in (False, True):
            for key in hists[hists.keys()[0]]["hists"]:

                canvas = Plotter.Canvas(logy=is_logy, lumi=lumi_str)

                statsboxes = {
                }  # keep references to stats boxes so they don't vanish

                cnt_file = -1  # keeps track of the number of processed files
                for f in hists:
                    cnt_file += 1
                    canvas.addMainPlot(plots[f]["plots"][key])
                    RT.addBinWidth(plots[f]["plots"][key])
                    plots[f]["plots"][key].SetLineColor(
                        plots[f]["appearance"][0])
                    plots[f]["plots"][key].SetLineStyle(
                        plots[f]["appearance"][1])
                    if plots[f]["appearance"][2] is not None:
                        plots[f]["plots"][key].SetMarkerStyle(
                            plots[f]["appearance"][2])

                    statsboxes[f] = canvas.makeStatsBox(
                        plots[f]["plots"][key],
                        color=plots[f]["appearance"][0],
                        entries=('nentries'))
                    Plotter.MOVE_OBJECT(statsboxes[f],
                                        Y=-.04 * (len(statsboxes) - 1) - 0.1)

                if legName != "":
                    canvas.makeLegend(lWidth=0.3, pos="br", fontscale=0.77)
                    canvas.legend.resizeHeight()
                    canvas.legend.moveLegend(X=-0.25, Y=+0.15)

                # pave_triggerinfo = R.TPaveText(0.28, 0.75, 0.9, 0.9, "NDCNB")
                # pave_triggerinfo.SetTextAlign(13)
                # pave_triggerinfo.SetTextFont(42)
                # # pave_triggerinfo.SetTextSize(self.fontsize*.9)
                # pave_triggerinfo.SetMargin(0)
                # pave_triggerinfo.SetFillStyle(0)
                # pave_triggerinfo.SetFillColor(0)
                # pave_triggerinfo.SetLineStyle(0)
                # pave_triggerinfo.SetLineColor(0)
                # pave_triggerinfo.SetBorderSize(0)
                # pave_triggerinfo.AddText(0.0, 1.0, HLT_info)
                # pave_triggerinfo.AddText(0.0, 0.5, L1T_info)
                # pave_triggerinfo.Draw()

                # d0min_searchres = re.search(r"__d0GT(\d+p\d+|\d+)", key)
                # if d0min_searchres:
                #     d0min = d0min_searchres.group(1).replace("p", ".")
                # else:
                #     d0min = None

                # d0max_searchres = re.search(r"__d0LT(\d+p\d+|\d+)", key)
                # if d0max_searchres:
                #     d0max = d0max_searchres.group(1).replace("p", ".")
                # else:
                #     d0max = None

                # if d0min is not None and d0max is not None:
                #     selection_str = R.TLatex()
                #     selection_str.SetTextSize(0.035)
                #     selection_str.DrawLatexNDC(
                #         0.4, 0.73, "{} cm  < d_{{0}} < {} cm".format(d0min, d0max)
                #     )

                # find the corresponding d0 distribution in the given d0 bin
                # and display its mean
                current_var = re.search(r"__(.+)VAR", key)
                if current_var:
                    current_var = current_var.group(1)
                    # current_var = re.findall(r"__(.+)VAR", key)
                    # if len(current_var) == 1:
                    # current_var = current_var[0].split("_")[-1]
                    if all([c in key for c in ("__d0GT", "__d0LT")]):
                        cnt_d0infos = 0
                        pave_d0info = {}

                        for f in hists:
                            d0_distribution = h_d0[f][key]
                            d0_hist = key.replace(
                                "__{}VAR".format(current_var), "__d0VAR")
                            d0_mean = d0_distribution.GetMean()

                            pT_mean = h_pT[f][key].GetMean()

                            # eta_mean = h_eta[f][key].GetMean()
                            # eta_mean = mean([h_eta[f][key].GetBinContent(i) for i in range(1, h_eta[f][key].GetNbinsX()+1)])
                            eta_absmean = 0.0
                            for i in range(1, h_eta[f][key].GetNbinsX() + 1):
                                if h_eta[f][key].GetXaxis().GetBinCenter(
                                        i) < 0:
                                    eta_absmean += (
                                        -1
                                    ) * h_eta[f][key].GetXaxis().GetBinCenter(
                                        i) * h_eta[f][key].GetBinContent(i)
                                else:
                                    eta_absmean += h_eta[f][key].GetXaxis(
                                    ).GetBinCenter(
                                        i) * h_eta[f][key].GetBinContent(i)

                            eta_mean = eta_absmean / h_eta[f][key].GetEntries()

                            d0_min = re.findall(r"__d0GT(\d+)p(\d+)", d0_hist)
                            if len(d0_min) > 0:
                                d0_min = float("{}.{}".format(
                                    d0_min[0][0], d0_min[0][1]))
                            else:
                                d0_min = float(
                                    re.findall(r"__d0GT(\d+)", d0_hist)[0])

                            d0_max = re.findall(r"__d0LT(\d+)p(\d+)", d0_hist)
                            if len(d0_max) > 0:
                                d0_max = float("{}.{}".format(
                                    d0_max[0][0], d0_max[0][1]))
                            else:
                                d0_max = float(
                                    re.findall(r"__d0LT(\d+)", d0_hist)[0])

                            d0info_width = 0.15
                            d0info_height = 0.14

                            pave_d0info[f] = R.TPaveText(
                                0.15 + cnt_d0infos * d0info_width,
                                0.75,  # + cnt_d0infos * d0info_height,
                                0.15 + (cnt_d0infos + 1) * d0info_width,
                                0.75 +
                                d0info_height,  # + (cnt_d0infos+1) * d0info_height,
                                "NDCNB")
                            pave_d0info[f].SetTextAlign(13)
                            pave_d0info[f].SetTextFont(42)
                            pave_d0info[f].SetMargin(0)
                            pave_d0info[f].SetFillStyle(0)
                            pave_d0info[f].SetFillColor(0)
                            pave_d0info[f].SetLineStyle(0)
                            pave_d0info[f].SetLineColor(0)
                            pave_d0info[f].SetBorderSize(0)
                            pave_d0info[f].SetTextColor(
                                hists[f]["appearance"][0])
                            pave_d0info[f].AddText(
                                0.0, 1.0, "{} cm < d_{{0}} < {} cm".format(
                                    d0_min, d0_max))
                            pave_d0info[f].AddText(
                                0.0, .66,
                                "#LTd_{{0}}#GT = {:4.3f} cm".format(d0_mean))
                            pave_d0info[f].AddText(
                                0.0, .33,
                                "#LTp_{{T}}#GT = {:4.3f} GeV".format(pT_mean))
                            pave_d0info[f].AddText(
                                0.0, 0.0,
                                "#LT|#eta|#GT = {:4.3f}".format(eta_mean))
                            pave_d0info[f].Draw()

                            cnt_d0infos += 1

                # set custom x axis range if so specified in the variable custom_xranges
                for var in custom_xranges:
                    if var in key:
                        canvas.firstPlot.GetXaxis().SetRangeUser(
                            custom_xranges[var][0], custom_xranges[var][1])
                        break

                if "norm" in suffix:
                    if is_logy:
                        canvas.firstPlot.GetYaxis().SetRangeUser(1e-3, 0.5)
                    else:
                        canvas.firstPlot.GetYaxis().SetRangeUser(0.0, 0.5)

                if "norm" in suffix:
                    canvas.firstPlot.GetYaxis().SetTitle(
                        "Normalized " + canvas.firstPlot.GetYaxis().GetTitle())

                fname = "{}/{}{}{}".format(output_folder, key,
                                           "_logy" if is_logy else "", suffix)

                canvas.finishCanvas()
                canvas.save(fname, extList=output_formats)
                canvas.deleteCanvas()

    del hists
示例#21
0
def makeOverlaidResPlot(MUONS, fs, sp, quantity, outputTag=None):
    # whether the plot is dif or res makes a difference wrt binning, fit range, and stats box positions
    # only pT is a res type; the others are all dif types
    ISDIF = quantity != 'pT'

    # what to name the plot. if MUONS is length 1, no sense to pass it twice, so get it automatically
    if outputTag is None:
        outputTag = MUONS[0]

    # colors, in order of MUONS, and also hashed
    defaultColorOrder = (R.kBlue, R.kRed, R.kGreen)
    colorDict = dict(zip(MUONS, defaultColorOrder))

    # get histograms and define plots
    h = {}
    for MUON in MUONS:
        h[MUON] = HistogramGetter.getHistogram(f, (fs, sp), MUON+'_'+quantity+'Res').Clone()
    p = {}
    for MUON in MUONS:
        RT.addFlows(h[MUON])
        if not ISDIF:
            h[MUON].Rebin(5)
        else:
            h[MUON].Rebin(10)
        p[MUON] = Plotter.Plot(h[MUON], 'Signal MC ({})'.format(MUON[:3]), 'l', 'hist')

    # define and fit gaussians to everything. Set FITRANGE to be something useful.
    funcs = {}
    fplots = {}
    for MUON in MUONS:
        if quantity == 'pT':
            FITRANGE = (-0.4, 0.3)
        elif quantity == 'eta':
            FITRANGE = (-0.1, 0.1)
        else:
            FITRANGE = (-20., 20.)
        funcs[MUON] = R.TF1('f'+MUON, 'gaus', *FITRANGE)
        h[MUON].Fit('f'+MUON, 'R')
        fplots[MUON] = Plotter.Plot(funcs[MUON], 'Gaussian fit ({})'.format(MUON[:3]), 'l', '')

    # define canvas, add plots. addS is so that statsbox will be drawn later.
    # these all should be pretty obvious until...
    canvas = Plotter.Canvas(lumi=SPLumiStr(fs, *sp))
    for i, MUON in enumerate(MUONS):
        canvas.addMainPlot(p[MUON], addS=True if i!=0 else False)
        canvas.addMainPlot(fplots[MUON])

    if len(MUONS) > 1:
        canvas.firstPlot.setTitles(X=canvas.firstPlot.GetXaxis().GetTitle().replace(MUONS[0],'Reco'))

    canvas.makeLegend(lWidth=.25, pos='tl')
    canvas.legend.resizeHeight()

    for MUON in MUONS:
        p     [MUON].SetLineColor(colorDict[MUON]  )
        fplots[MUON].SetLineColor(colorDict[MUON]+1)

    RT.addBinWidth(canvas.firstPlot)

    # dif type: fit boxes go down the left side
    # res type: fit boxes go down the middle
    # stats boxes are on the right
    paves = []
    for i, MUON in enumerate(MUONS):
        paves.append(canvas.makeStatsBox(p[MUON], color=colorDict[MUON]))
        Plotter.MOVE_OBJECT(paves[-1], Y=-.2*i)

        if not ISDIF:
            canvas.setFitBoxStyle(h[MUON], lWidth=0.275, pos='tr')
        else:
            canvas.setFitBoxStyle(h[MUON], lWidth=0.275, pos='tl')

        sbox = p[MUON].FindObject('stats')
        sbox.SetTextColor(colorDict[MUON]+1)

        if not ISDIF:
            Plotter.MOVE_OBJECT(sbox, Y=-.15*i, X=-.18, NDC=True)
        else:
            Plotter.MOVE_OBJECT(sbox, Y=-.15*i-0.04*4.1, NDC=True)

    fname = 'pdfs/SRR_{}_{}_{}HTo2XTo{}_{}.pdf'.format(outputTag, quantity+'Res', 'Trig-' if TRIGGER else '', fs, SPStr(sp))
    canvas.cleanup(fname)
def makeTurnOnComparisonPlots():
    turnOn_patterns_and_excludes = (
        ("__pTVAREff",
         ["DSA__pTVAREff", "upperLeg", "_0p0alpha", "_0p3alpha", "_2p8alpha"]),
        # do not list any other tuples here, they will not be processed
    )

    # these intervals must be equal (or a subset) of the ones defined in the
    # ../analyzers/cosmicsPlots.py script
    d0intervals = [(None, None)]
    # d0intervals += [(i,i+2.5) for i in np.arange(0., 10., 2.5)]
    # d0intervals += [(i,i+5.0) for i in np.arange(0., 20., 5.0)]
    # d0intervals += [(i,i+10.0) for i in np.arange(20., 100., 10.0)]
    d0intervals += [
        (0, 10),
        (0, 50),
        (10, 50),
        (50, 100),
        (100, 150),
        (150, 250),
        (250, 350),
        (250, 1000),
    ]

    hists = collectHistograms(file_specs, turnOn_patterns_and_excludes)

    # prepare the histograms
    for app, f, f_descr in file_specs:
        for key in hists[f]["hists"]:
            RT.addFlows(hists[f]["hists"][key])

            if hists[f]["hists"][key].GetNbinsX() >= 1000:
                hists[f]["hists"][key].Rebin(5)
            elif hists[f]["hists"][key].GetNbinsX() >= 100:
                hists[f]["hists"][key].Rebin(5)
            else:
                pass

            legName = f_descr

    for d0min, d0max in d0intervals:
        hden = {f: {} for __, f, __ in file_specs}
        hnum = {f: {} for __, f, __ in file_specs}
        p = {
            f: {
                "appearance": app,
                "descr": d,
                "plots": {}
            }
            for app, f, d in file_specs
        }
        g = {
            f: {
                "appearance": app,
                "descr": d,
                "plots": {}
            }
            for app, f, d in file_specs
        }

        for app, f, f_descr in file_specs:
            if d0min is None or d0max is None:
                hnums = [
                    h for h in hists[f]["hists"]
                    if turnOn_patterns_and_excludes[0][0] + "Num" in h and
                    not any([d0_str in h for d0_str in ("__d0GT", "__d0LT")])
                ]
                hdens = [
                    h for h in hists[f]["hists"]
                    if turnOn_patterns_and_excludes[0][0] + "Den" in h and
                    not any([d0_str in h for d0_str in ("__d0GT", "__d0LT")])
                ]

            else:
                hnums = [
                    h for h in hists[f]["hists"] if all([
                        s in h for s in (
                            turnOn_patterns_and_excludes[0][0] + "Num",
                            "__d0GT" + str(d0min).replace(".", "p"),
                            "__d0LT" + str(d0max).replace(".", "p"),
                        )
                    ])
                ]

                hdens = [
                    h for h in hists[f]["hists"] if all([
                        s in h for s in (
                            turnOn_patterns_and_excludes[0][0] + "Den",
                            "__d0GT" + str(d0min).replace(".", "p"),
                            "__d0LT" + str(d0max).replace(".", "p"),
                        )
                    ])
                ]

            for hname in hnums:
                current_hist = hists[f]["hists"][hname].Clone()
                current_hist.SetDirectory(0)
                current_hist.Sumw2()
                RT.addFlows(current_hist)

                if hname not in hnum[f].keys():
                    hnum[f][hname] = current_hist
                else:
                    hnum[f][hname].Add(current_hist)

            for hname in hdens:
                current_hist = hists[f]["hists"][hname].Clone()
                current_hist.SetDirectory(0)
                current_hist.Sumw2()
                RT.addFlows(current_hist)

                if hname not in hden[f].keys():
                    hden[f][hname] = current_hist
                else:
                    hden[f][hname].Add(current_hist)

        if len(hden[f]) > 1:
            raise NotImplementedError(
                "Too many denumerator histos - not yet implemented")
        elif len(hden[f]) == 0:
            raise Exception("No denominator histogram found")

        # works only if consistency checks of the collectHistograms() function
        # pass (i.e., if all files have the same histogram content)
        for key in hnum[file_specs[0][1]]:
            canvas = Plotter.Canvas(lumi=lumi_str)

            cnt_file = 0  # keep track of the order of processed files
            for app, f, f_descr in file_specs:
                try:
                    hden[f] = hden[f][hden[f].keys()[0]]
                except:
                    pass

                g[f][key] = R.TGraphAsymmErrors(hnum[f][key], hden[f], "cp")
                g[f][key].SetNameTitle(
                    "g_" + f + "_" + key,
                    ";" + hnum[f][key].GetXaxis().GetTitle() + ";Efficiency",
                )
                p[f][key] = Plotter.Plot(g[f][key], f_descr, "elp", "pe")

                canvas.addMainPlot(p[f][key])
                p[f][key].setColor(app[0])
                if app[2] is not None:
                    p[f][key].SetMarkerStyle(app[2])

                cnt_file += 1

            canvas.makeLegend(pos="br", fontscale=0.77)
            canvas.legend.moveLegend(X=-0.45, Y=0.08)
            canvas.legend.resizeHeight()
            canvas.firstPlot.GetXaxis().SetRangeUser(0.0, 150.0)
            canvas.firstPlot.GetYaxis().SetRangeUser(0.0, 1.055)

            # L2pTcut = re.findall(r"_pTGT(\d+)p(\d+)", key)
            L2pTcut = re.findall(r"_L2pTGT(\d+)p(\d+)", key)
            if len(L2pTcut) > 1:
                raise Exception("Ambiguitites in L2 pT threshold "
                                "identification: {}".format(L2pTcut))
            L2pTcut = float(".".join(L2pTcut[0]))
            pTthreshold_str = R.TLatex()
            pTthreshold_str.SetTextSize(0.035)
            pTthreshold_str.DrawLatex(
                100.0, 0.75, "p_{{T}}^{{L2}} > {} GeV".format(L2pTcut))

            if L2pTcut > 0.0:
                L2vline = R.TLine(L2pTcut, 1.0, 150.0, 1.0)
                R.SetOwnership(L2vline, 0)
                L2vline.SetLineColor(15)
                L2vline.SetLineStyle(1)
                L2vline.Draw()

            L1pTcut = re.findall(r"_L1pTGT(\d+)p(\d+)", key)
            if len(L1pTcut) > 1:
                raise Exception(
                    "Ambiguities in L1 pT threshold identification: {}".format(
                        L1pTcut))
            elif len(L1pTcut) == 0:
                raise Exception(
                    "No L1 pT threshold identified in {}".format(key))

            L1pTcut = float(".".join(L1pTcut[0]))
            pTthreshold_str = R.TLatex()
            pTthreshold_str.SetTextSize(0.035)
            pTthreshold_str.DrawLatex(
                100.0, 0.66, "p_{{T}}^{{L1}} > {} GeV".format(L1pTcut))

            if L1pTcut > 0.0:
                L1vline = R.TLine(L1pTcut, 1.0,
                                  (L2pTcut if L2pTcut > 0.0 else 150.0), 1.0)
                R.SetOwnership(L1vline, 0)
                L1vline.SetLineColor(15)
                L1vline.SetLineStyle(3)
                L1vline.Draw()

            if d0min is not None and d0max is not None:
                selection_str = R.TLatex()
                selection_str.SetTextSize(0.035)
                selection_str.DrawLatex(
                    100.0, 0.57,
                    "{} cm  < d_{{0}} < {} cm".format(d0min, d0max))

            pave_triggerinfo = R.TPaveText(0.4, 0.11, 0.92, 0.28, "NDCNB")
            pave_triggerinfo.SetTextAlign(13)
            pave_triggerinfo.SetTextFont(42)
            # pave_triggerinfo.SetTextSize(self.fontsize*.9)
            pave_triggerinfo.SetMargin(0)
            pave_triggerinfo.SetFillStyle(0)
            pave_triggerinfo.SetFillColor(0)
            pave_triggerinfo.SetLineStyle(0)
            pave_triggerinfo.SetLineColor(0)
            pave_triggerinfo.SetBorderSize(0)
            pave_triggerinfo.AddText(0.0, 1.0, HLT_info)
            pave_triggerinfo.AddText(0.0, 0.5, L1T_info)
            pave_triggerinfo.Draw()

            fname = "{}/TETurnOn_{}".format(output_folder, key)

            canvas.finishCanvas()
            canvas.save(fname, extList=output_formats)
            canvas.deleteCanvas()

    del hists
def makeEffPlots(quantity, fs, SP=None):
    HKeys = {
        'GEN_Eff': 'GEN_{}Eff',
        'GEN_Den': 'GEN_{}Den',
        'DSA_Eff': 'DSA_{}Eff',
        'DSA_Den': 'DSA_{}Den',
        'RSA_Eff': 'RSA_{}Eff',
        'RSA_Den': 'RSA_{}Den',
    }
    for key in HKeys:
        HKeys[key] = HKeys[key].format(quantity, 'HTo2XTo' + fs)

    h = {}
    p = {}
    g = {}
    hm = {}

    if SP is None:
        for i, sp in enumerate(SIGNALPOINTS):
            if i == 0:
                for key in HKeys:
                    h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
                    h[key].SetDirectory(0)
            else:
                for key in HKeys:
                    h[key].Add(HISTS[(fs, sp)][HKeys[key]])
    else:
        sp = SP
        for key in HKeys:
            h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
            h[key].SetDirectory(0)

    for key in HKeys:
        RT.addFlows(h[key])
        h[key].Rebin(10)

    NumDens = (
        ('GEN_Eff', 'GEN_Den', 'GEN', R.kGreen),
        ('DSA_Eff', 'DSA_Den', 'DSA', R.kBlue),
        ('RSA_Eff', 'RSA_Den', 'RSA', R.kRed),
    )

    for num, den, leg, col in NumDens:
        g[num] = R.TGraphAsymmErrors(h[num], h[den], 'cp')
        g[num].SetNameTitle(
            'g_' + num,
            ';' + h[num].GetXaxis().GetTitle() + '; Trigger Efficiency')
        g[num].GetXaxis().SetRangeUser(0, 100)
        p[num] = Plotter.Plot(g[num], leg, 'elp', 'pe')

        h[num].Sumw2()
        h[den].Sumw2()


#         # ratio_hist = h[num]
#         # ratio_hist.Divide(h[den])
#         # eff_sum_num = 0
#         # eff_sum_den = 0
#         # if quantity == 'pT':
#         #     for binx in range(1, h[num].GetXaxis().GetNbins()+1):
#         #         if h[num].GetBinLowEdge(binx) < 30.: continue
#         #         efferror = ratio_hist.GetBinError(binx)
#         #         if efferror != 0:
#         #             eff_sum_num += ratio_hist.GetBinContent(binx) / \
#         #                     (efferror*efferror)
#         #             if ratio_hist.GetBinContent(binx) != 0:
#         #                 eff_sum_den += 1/(efferror*efferror)
#         #     if eff_sum_den != 0:
#         #         hm[num] = eff_sum_num / eff_sum_den

#         ratio_hist = R.TEfficiency(h[num], h[den])
#         eff_sum_num = 0
#         eff_sum_den = 0
#         if quantity == 'pT':
#             for binx in range(1, h[num].GetXaxis().GetNbins()+2):
#                 if h[num].GetBinLowEdge(binx) < 30.: continue
#                 glob_bin = ratio_hist.GetGlobalBin(binx)
#                 efferror = max(ratio_hist.GetEfficiencyErrorLow(glob_bin),
#                         ratio_hist.GetEfficiencyErrorUp(glob_bin))
#                 if efferror != 0:
#                     eff_sum_num += ratio_hist.GetEfficiency(glob_bin) / \
#                             (efferror*efferror)
#                     if ratio_hist.GetEfficiency(glob_bin) != 0:
#                         eff_sum_den += 1/(efferror*efferror)
#             if eff_sum_den != 0:
#                 hm[num] = eff_sum_num / eff_sum_den

    FIRST = (0, 3)
    # SECOND = (3, 5)
    CHARGE = ''
    for SECTION in (FIRST, ):
        fraction_str = '' if SP is None else '[{}%, {}%]'.format(
            round(FRACTIONS[fs]['{}_{}_{}'.format(*SP)][0], 1),
            round(FRACTIONS[fs]['{}_{}_{}'.format(*SP)][1], 1))
        canvas = Plotter.Canvas(
            lumi=fs if SP is None else
            '{} ({} GeV, {} GeV, {} mm) #scale[0.7]{{{fraction_str}}}'.
            format(fs, *SP, fraction_str=fraction_str))
        for i in range(SECTION[0], SECTION[1]):
            key = NumDens[i][0]
            col = NumDens[i][3]
            canvas.addMainPlot(p[key])
            p[key].SetMarkerColor(col)
            p[key].SetLineColor(col)

            if quantity == 'pT':
                axis_max = p[NumDens[SECTION[0]][0]].GetXaxis().GetBinLowEdge(
                    p[NumDens[SECTION[0]][0]].GetXaxis().GetNbins())
                hline = R.TLine(30., hm[key], axis_max, hm[key])
                R.SetOwnership(hline, 0)
                hline.SetLineColor(col)
                hline.Draw()

        canvas.makeLegend(pos='tl')
        # canvas.legend.moveLegend(X=0.08)
        canvas.legend.resizeHeight()
        canvas.firstPlot.SetMinimum(0.)
        canvas.firstPlot.SetMaximum(1.)
        RT.addBinWidth(canvas.firstPlot)
        if quantity == 'pT':
            vline = R.TLine(28., 0., 28., 1.)  # draw vertical line at 28 GeV
            vline.SetLineColor(15)
            vline.Draw()

        canvas.cleanup('pdfs/STETurnOn_zoomed_{}{}Eff_HTo2XTo{}_{}.pdf'.format(
            quantity, CHARGE, fs, 'Global' if SP is None else SPStr(SP)))
        CHARGE = 'Charge'
示例#24
0
def makeEffPlots(quantity, fs, SP=None):
    HKeys = {
        'DSA_Num': 'DSADim_Num_{}',
        'DSA_Den': 'DSADim_Den_{}',
    }
    for key in HKeys:
        HKeys[key] = HKeys[key].format(quantity, 'HTo2XTo' + fs)

    h = {}
    pg = {}
    pnum = {}
    pden = {}
    prn = {}
    prd = {}
    g = {}
    rn = {}
    rd = {}

    if SP is None:
        for i, sp in enumerate(SIGNALPOINTS):
            if i == 0:
                for key in HKeys:
                    h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
                    h[key].SetDirectory(0)
            else:
                for key in HKeys:
                    h[key].Add(HISTS[(fs, sp)][HKeys[key]])

        displacement_str = None
        displacement_color = None
    else:
        sp = SP
        if isinstance(sp, tuple):
            for key in HKeys:
                h[key] = HISTS[(fs, sp)][HKeys[key]].Clone()
                h[key].SetDirectory(0)

                h[key].GetXaxis().SetLimits(limit_low, limit_high)
                h[key].GetXaxis().SetRangeUser(limit_low, limit_high)
                RT.addFlows(h[key])
                h[key].Rebin(10)
                h[key].Sumw2()
        elif isinstance(sp, list):
            h[key] = {}
            for key in HKeys:
                for spl in sp:
                    h[key][spl] = HISTS[(fs, spl)][HKeys[key]].Clone()
                    h[key][spl].SetDirectory(0)
                    h[key][spl].GetXaxis().SetLimits(limit_low, limit_high)
                    RT.addFlows(h[key][spl])
                    h[key][spl].Rebin(10)
                    h[key][spl].Sumw2()

        dxy_fraction = round(FRACTIONS[fs]['{}_{}_{}'.format(*SP)][1], 1)
        for key in DISPLACEMENT_CATEGORIES:
            if key[0] <= dxy_fraction < key[1]:
                displacement_str = DISPLACEMENT_CATEGORIES[key]['label']
                displacement_color = DISPLACEMENT_CATEGORIES[key]['color']
                break
        else:
            # we must have dxy_fractions == 100.0
            key = DISPLACEMENT_CATEGORIES.keys()[-1]
            displacement_str = DISPLACEMENT_CATEGORIES[key]['label']
            displacement_color = DISPLACEMENT_CATEGORIES[key]['color']


#     for key in HKeys:
#         RT.addFlows(h[key])
#         h[key].Rebin(10)
#         # area = h[key].Integral()
#         h[key].Sumw2()
#         # if area != 0: h[key].Scale(1./area)

    NumDens = (
        ('DSA_Num', 'DSA_Den', 'GEN', R.kBlue),
        ('DSA_Num', 'DSA_Den', ('untriggered', 'triggered'), (R.kBlue,
                                                              R.kRed)),
    )

    num, den, leg, col = NumDens[0]
    g[num] = R.TGraphAsymmErrors(h[num], h[den], 'cp')
    g[num].GetXaxis().SetLimits(limit_low, limit_high)
    g[num].SetNameTitle(
        'g_' + num,
        ';' + h[num].GetXaxis().GetTitle() + '; Trigger Efficiency')
    pg[num] = Plotter.Plot(g[num], leg, 'elp', 'pe')

    num, den, leg, col = NumDens[1]
    pnum[num] = Plotter.Plot(deepcopy(h[num]), leg[1], 'elp', 'pe')
    pden[num] = Plotter.Plot(deepcopy(h[den]), leg[0], 'elp', 'pe')
    pnum[num].SetNameTitle('pnum_' + num,
                           ';' + h[num].GetXaxis().GetTitle() + '; yield')
    rn[num] = deepcopy(h[num])
    rn[num].Scale(1. / (h[num].Integral()))
    rn[num].SetNameTitle('rn_' + num,
                         ';' + h[num].GetXaxis().GetTitle() + '; norm. yield')
    # rn[num].GetXaxis().SetRangeUser(0, 100)
    prn[num] = Plotter.Plot(rn[num], leg[1], 'elp', 'pe')
    rd[num] = deepcopy(h[den])
    rd[num].Scale(1. / (h[den].Integral()))
    rd[num].SetNameTitle('rd_' + num,
                         ';' + h[num].GetXaxis().GetTitle() + '; norm. yield')
    prd[num] = Plotter.Plot(rd[num], leg[0], 'elp', 'pe')

    FIRST = (0, 1)
    SECOND = (1, 2)

    fraction_str = '' if SP is None else '[{}%, #color[{}]{{{}%}}]'.format(
        round(FRACTIONS[fs]['{}_{}_{}'.format(*SP)][0], 1), displacement_color,
        round(FRACTIONS[fs]['{}_{}_{}'.format(*SP)][1], 1))

    accepted_error_max = 0.1
    accepted_error_halfmax = 0.2

    for SECTION in (FIRST, ):
        canvas_eff = Plotter.Canvas(
            lumi=fs if SP is None else
            '{} ({} GeV, {} GeV, {} mm) #scale[0.7]{{{fraction_str}}}'.
            format(fs, *SP, fraction_str=fraction_str))
        for i in range(SECTION[0], SECTION[1]):
            key = NumDens[i][0]
            col = NumDens[i][3]
            # pg[key].GetXaxis().SetLimits(0., 3.5)
            canvas_eff.addMainPlot(pg[key])
            pg[key].SetMarkerColor(col)
            pg[key].SetLineColor(col)
            ymax = -1.
            ymaxErrorYlow = 0.
            ymaxErrorYhigh = 0.
            ymax_pos = None
            for b in range(pg[key].GetN(), 0, -1):
                xtemp = R.Double(-1.)
                ytemp = R.Double(-1.)
                pg[key].GetPoint(b, xtemp, ytemp)
                ytempErrorYlow = pg[key].GetErrorYlow(b)
                ytempErrorYhigh = pg[key].GetErrorYhigh(b)
                # if ytemp > ymax and max(pg[key].GetErrorYlow(b),
                #         pg[key].GetErrorYhigh(b)) < accepted_error_max:
                #     ymax = ytemp
                #     ymax_pos = xtemp

                # if point has a lower value than the one one the right, but it
                # is compatible with the fluctuations of the plot on the right
                # (i.e., its errors are contained in the errors of the other
                # plot), then call the (left) point the new maximum nevertheless
                if ytemp < ymax and max(ytempErrorYlow,
                        ytempErrorYhigh) < accepted_error_max and \
                                ytemp-ytempErrorYlow > ymax-ymaxErrorYlow and \
                                ytemp+ytempErrorYhigh < ymax+ymaxErrorYhigh:
                    ymax = ytemp
                    ymaxErrorYlow = ytempErrorYlow
                    ymaxErrorYhigh = ytempErrorYhigh
                    ymax_pos = xtemp

                elif ytemp > ymax and max(
                        ytempErrorYlow, ytempErrorYhigh) < accepted_error_max:
                    ymax = ytemp
                    ymaxErrorYlow = ytempErrorYlow
                    ymaxErrorYhigh = ytempErrorYhigh
                    ymax_pos = xtemp

            if ymax_pos is not None:
                maxarrow = R.TArrow(ymax_pos, -0.065, ymax_pos, 0.)
                R.SetOwnership(maxarrow, 0)
                maxarrow.SetLineColor(col)
                maxarrow.SetLineWidth(3)
                maxarrow.SetArrowSize(0.02)
                maxarrow.Draw()
            else:
                print('WARNING: No maximum found. Maybe the accepted errors '
                      'are too small?')
                ymax_pos = None
                yhalfmax_pos = None

            if ymax_pos is not None:
                yhalfmax = 0.5 * ymax
                yhalfmax_pos = None
                for b in range(pg[key].GetN()):
                    xtemp = R.Double(-1.)
                    ytemp = R.Double(-1.)
                    pg[key].GetPoint(b, xtemp, ytemp)
                    if ytemp > yhalfmax and max(
                            pg[key].GetErrorYlow(b),
                            pg[key].GetErrorYhigh(b)) < accepted_error_halfmax:
                        x2 = xtemp
                        y2 = ytemp
                        xtemp_prev = R.Double(0.)
                        ytemp_prev = R.Double(0.)
                        for bprev in range(1, b + 1):
                            if b - bprev >= 0 and max(
                                    pg[key].GetErrorYlow(b - bprev),
                                    pg[key].GetErrorYhigh(
                                        b - bprev)) < accepted_error_halfmax:
                                pg[key].GetPoint(b - bprev, xtemp_prev,
                                                 ytemp_prev)
                                x1 = xtemp_prev
                                y1 = ytemp_prev
                                # linear interpolation:
                                yhalfmax_pos = (yhalfmax * (x1 - x2) +
                                                (y1 * x2 - y2 * x1)) / (y1 -
                                                                        y2)
                                break
                        else:
                            yhalfmax_pos = x2 * 0.5

                        halfmaxarrow = R.TArrow(yhalfmax_pos, -0.06,
                                                yhalfmax_pos, 0.)
                        R.SetOwnership(halfmaxarrow, 0)
                        halfmaxarrow.SetLineColor(col)
                        halfmaxarrow.SetLineWidth(2)
                        halfmaxarrow.SetArrowSize(0.02)
                        halfmaxarrow.Draw()
                        break

        if ymax_pos is not None and yhalfmax_pos is not None:
            pg[key].legName = pg[key].legName + \
                    ' #scale[0.7]{{(#Delta R_{{max}} = {}, #Delta R_{{max/2}} = {}, #frac{{#Delta R_{{max/2}}}}{{#Delta R_{{max}}}} = {})}}'.format(
                        round(ymax_pos,3), round(yhalfmax_pos,3),
                        round(yhalfmax_pos/ymax_pos, 3))

        run1_line = R.TLine(0.2, 0., 0.2, 1.)
        R.SetOwnership(run1_line, 0)
        run1_line.SetLineColor(R.kGray)
        run1_line.Draw()

        canvas_eff.makeLegend(lWidth=0.65, pos='tr')
        # canvas_eff.legend.moveLegend(X=0.08)
        canvas_eff.legend.resizeHeight()
        # canvas_eff.firstPlot.GetXaxis().SetLimits(0., 3.5)
        canvas_eff.firstPlot.SetMinimum(0.)
        canvas_eff.firstPlot.SetMaximum(1.)
        RT.addBinWidth(canvas_eff.firstPlot)

        canvas_eff.cleanup('pdfs/DimSTE_{}{}Eff_HTo2XTo{}_{}_{}.pdf'.format(
            output_tag, quantity, fs, 'Global' if SP is None else SPStr(SP),
            (displacement_str if displacement_str is not None else '')))

    for SECTION in (SECOND, ):
        canvas_ratioplot = Plotter.Canvas(
            ratioFactor=1 / 3.,
            lumi=fs if SP is None else
            '{} ({} GeV, {} GeV, {} mm) #scale[0.7]{{{fraction_str}}}'.format(
                fs, *SP, fraction_str=fraction_str))
        for i in range(SECTION[0], SECTION[1]):
            key = NumDens[i][0]
            col = NumDens[i][3]
            # prn[key].GetXaxis().SetLimits(0., 3.5)
            # prd[key].GetXaxis().SetLimits(0., 3.5)
            canvas_ratioplot.makeLegend(lWidth=.35, pos='tr')
            canvas_ratioplot.addLegendEntry(prn[key])
            canvas_ratioplot.addLegendEntry(prd[key])
            canvas_ratioplot.legend.resizeHeight()
            canvas_ratioplot.addMainPlot(prn[key])
            canvas_ratioplot.addMainPlot(prd[key])
            canvas_ratioplot.makeRatioPlot(prn[key],
                                           prd[key],
                                           ytit='triggered / untriggered')
            canvas_ratioplot.firstPlot.scaleTitleOffsets(0.8, axes='Y')
            canvas_ratioplot.rat.scaleTitleOffsets(0.8, axes='Y')
            vline = R.TLine(2.5, 0.5, 2.5, 1.5)
            R.SetOwnership(vline, 0)
            vline.SetLineColor(15)
            vline.Draw()
            prn[key].SetMarkerColor(col[0])
            prn[key].SetLineColor(col[0])
            prd[key].SetMarkerColor(col[1])
            prd[key].SetLineColor(col[1])
        # canvas_ratioplot.makeLegend(pos='tr')
        # canvas_ratioplot.legend.moveLegend(X=0.08)
        # canvas_ratioplot.legend.resizeHeight()
        # canvas_ratioplot.firstPlot.SetMinimum(0.)
        # canvas_ratioplot.firstPlot.SetMaximum(1.)
        # vline = R.TLine(0., 1., 5., 1.)
        # R.SetOwnership(vline, 0)
        # vline.SetLineColor(15)
        # vline.Draw()
        # RT.addBinWidth(canvas_ratioplot.firstPlot)
        # canvas_ratioplot.finishCanvas(extrascale=1.+1/3.)
        canvas_ratioplot.cleanup(
            'pdfs/DimSTE_{}{}NormRatio_HTo2XTo{}_{}_{}.pdf'.format(
                output_tag, quantity, fs,
                'Global' if SP is None else SPStr(SP),
                (displacement_str if displacement_str is not None else '')))

        canvas_overlay = Plotter.Canvas(
            lumi=fs if SP is None else
            '{} ({} GeV, {} GeV, {} mm) #scale[0.7]{{{fraction_str}}}'.
            format(fs, *SP, fraction_str=fraction_str))
        for i in range(SECTION[0], SECTION[1]):
            key = NumDens[i][0]
            col = NumDens[i][3]
            canvas_overlay.addMainPlot(pden[num])
            canvas_overlay.addMainPlot(pnum[num])
            canvas_overlay.makeLegend(pos='tr', lWidth=.2)
            canvas_overlay.legend.resizeHeight()
            # canvas_overlay.firstPlot.GetXaxis().SetLimits(0., 3.5)
            pnum[num].SetMarkerColor(col[0])
            pden[num].SetMarkerColor(col[1])
            pnum[num].SetLineColor(col[0])
            pden[num].SetLineColor(col[1])
        canvas_overlay.cleanup('pdfs/DimSTE_{}Overlay{}_{}_{}.pdf'.format(
            quantity, fs, 'Global' if SP is None else SPStr(SP),
            (displacement_str if displacement_str is not None else '')))
def makeTurnOnPlots():

    # these intervals must be equal (or a subset) of the ones defined in the
    # ../analyzers/cosmicsPlots.py script
    d0intervals = [(None, None)]
    # d0intervals += [(i,i+2.5) for i in np.arange(0., 10., 2.5)]
    # d0intervals += [(i,i+5.0) for i in np.arange(0., 20., 5.0)]
    # d0intervals += [(i,i+10.0) for i in np.arange(20., 100., 10.0)]
    d0intervals += [
        (0, 10),
        (10, 50),
        (50, 100),
        (100, 150),
        (150, 250),
        (250, 350),
        (250, 1000),
    ]

    for d0min, d0max in d0intervals:
        hden = {}
        hnum = {}
        p = {}
        g = {}
        for i, dataset in enumerate(HISTS):
            if d0min is None or d0max is None:
                hnums = getHistNames(
                    dataset, "DSA_lowerLeg", "pTVAREffNum", exclude=["d0GT", "d0LT", "alpha"]
                )
                hdens = getHistNames(
                    dataset, "DSA_lowerLeg", "pTVAREffDen", exclude=["d0GT", "d0LT", "alpha"]
                )
            else:
                hnums = getHistNames(
                    dataset,
                    "DSA_lowerLeg__pTVAREffNum",
                    "d0GT" + str(d0min).replace(".", "p"),
                    "d0LT" + str(d0max).replace(".", "p"),
                    exclude=["alpha"],
                )
                hdens = getHistNames(
                    dataset,
                    "DSA_lowerLeg__pTVAREffDen",
                    "d0GT" + str(d0min).replace(".", "p"),
                    "d0LT" + str(d0max).replace(".", "p"),
                    exclude=["alpha"],
                )

            for hname in hnums:
                current_hist = HISTS[dataset][hname].Clone()
                current_hist.SetDirectory(0)
                current_hist.Sumw2()
                RT.addFlows(current_hist)
                if current_hist.GetNbinsX() >= 1000:
                    current_hist.Rebin(15)
                elif current_hist.GetNbinsX() >= 100:
                    current_hist.Rebin(5)
                else:
                    pass

                if i == 0:
                    hnum[hname] = current_hist
                else:
                    hnum[hname].Add(current_hist)

            for hname in hdens:
                current_hist = HISTS[dataset][hname].Clone()
                current_hist.SetDirectory(0)
                current_hist.Sumw2()
                RT.addFlows(current_hist)
                if current_hist.GetNbinsX() >= 1000:
                    current_hist.Rebin(15)
                elif current_hist.GetNbinsX() >= 100:
                    current_hist.Rebin(5)
                else:
                    pass

                if i == 0:
                    hden[hname] = current_hist
                else:
                    hden[hname].Add(current_hist)

        if len(hden) > 1:
            raise NotImplementedError(
                "Too many denumerator histos - not yet implemented"
            )
        elif len(hden) == 0:
            raise Exception("No denominator histogram found")
        hden = hden[hden.keys()[0]]

        for key in hnum:
            canvas = Plotter.Canvas(lumi="NoBPTXRun2016D-07Aug17")

            g[key] = R.TGraphAsymmErrors(hnum[key], hden, "cp")
            g[key].SetNameTitle(
                "g_" + key, ";" + hnum[key].GetXaxis().GetTitle() + ";Efficiency"
            )
            p[key] = Plotter.Plot(g[key], key, "elp", "pe")

            canvas.addMainPlot(p[key])
            p[key].setColor(R.kBlue)
            canvas.makeLegend(pos="br")
            canvas.legend.moveLegend(X=-0.47)
            canvas.legend.moveLegend(Y=0.05)
            canvas.legend.resizeHeight()
            canvas.firstPlot.GetXaxis().SetRangeUser(0.0, 150.0)
            canvas.firstPlot.GetYaxis().SetRangeUser(0.0, 1.1)

            L2pTcut = re.findall(r"_pTGT(\d+)p(\d+)", key)
            if len(L2pTcut) > 1:
                raise Exception(
                    "Ambiguities in L2 pT threshold identification: {}".format(L2pTcut)
                )

            L2pTcut = float(".".join(L2pTcut[0]))
            pTthreshold_str = R.TLatex()
            pTthreshold_str.SetTextSize(0.035)
            pTthreshold_str.DrawLatex(
                100.0, 0.56, "p_{{T}}^{{L2}} > {} GeV".format(L2pTcut)
            )

            if L2pTcut > 0.0:
                L2vline = R.TLine(L2pTcut, 0.0, L2pTcut, 1.0)
                R.SetOwnership(L2vline, 0)
                L2vline.SetLineColor(15)
                L2vline.SetLineStyle(1)
                L2vline.Draw()

            L1pTcut = re.findall(r"_L1pTGT(\d+)p(\d+)", key)
            if len(L1pTcut) > 1:
                raise Exception(
                    "Ambiguities in L1 pT threshold identification: {}".format(L1pTcut)
                )
            elif len(L1pTcut) == 0:
                raise Exception("No L1 pT threshold identified in {}".format(key))

            L1pTcut = float(".".join(L1pTcut[0]))
            pTthreshold_str = R.TLatex()
            pTthreshold_str.SetTextSize(0.035)
            pTthreshold_str.DrawLatex(
                100.0, 0.48, "p_{{T}}^{{L1}} > {} GeV".format(L1pTcut)
            )

            if L1pTcut > 0.0:
                L1vline = R.TLine(L1pTcut, 0.0, L1pTcut, 1.0)
                R.SetOwnership(L1vline, 0)
                L1vline.SetLineColor(15)
                L1vline.SetLineStyle(2)
                L1vline.Draw()

            if d0min is not None and d0max is not None:
                selection_str = R.TLatex()
                selection_str.SetTextSize(0.035)
                selection_str.DrawLatex(
                    100.0, 0.4, "{} cm  < d_{{0}} < {} cm".format(d0min, d0max)
                )

            canvas.cleanup("pdfs/TETurnOn_{}.pdf".format(key))
            # hkey has the form KEY_HTo2XTo4Mu_mH_mX_cTau
            matches = Patterns['HTo2XTo4Mu'].match(hkey)
            fs = '4Mu'
        elif '2Mu2J' in hkey:
            # hkey has the form KEY_HTo2XTo2Mu2J_mH_mX_cTau
            matches = Patterns['HTo2XTo2Mu2J'].match(hkey)
            fs = '2Mu2J'
        key = matches.group(1)
        sp = tuple(map(int, matches.group(2, 3, 4)))
        if (fs, sp) not in HISTS:
            HISTS[(fs, sp)] = {}
        HISTS[(fs, sp)][key] = f.Get(hkey)
        HISTS[(fs, sp)][key].SetDirectory(0)

for sp in SIGNALPOINTS:
    RT.addFlows(HISTS[('2Mu2J', sp)]['goodChi2'])
    RT.addFlows(HISTS[('2Mu2J', sp)]['badChi2'])
    pGood = Plotter.Plot(HISTS[('2Mu2J', sp)]['goodChi2'], 'good', 'l', 'hist')
    pBad = Plotter.Plot(HISTS[('2Mu2J', sp)]['badChi2'], 'bad', 'l', 'hist')

    canvas = Plotter.Canvas(
        lumi='{} ({} GeV, {} GeV, {} mm)'.format('2Mu2J', *sp))
    canvas.addMainPlot(pGood)
    canvas.addMainPlot(pBad)

    canvas.makeLegend(pos='tl')

    pGood.SetLineColor(R.kBlue)
    pBad.SetLineColor(R.kRed)

    canvas.firstPlot.setTitles(X='vtx #chi^{2}/dof')
def makeStackPlots(DataMC=False, logy=False):
    BGORDER = ('WJets', 'WW', 'WZ', 'ZZ', 'tW', 'tbarW', 'ttbar',
               'QCD20toInf-ME', 'DY10to50', 'DY50toInf')
    for hkey in HISTS['DY50toInf']:
        if 'Matched' in hkey: continue
        if 'VS' in hkey: continue

        h = {}
        if not MCONLY:
            h['Data'] = HISTS['DoubleMuonRun2016B-07Aug17-v2'][hkey].Clone()
        if True:
            #           h      ['Signal'] = HISTS[('4Mu', (125, 20, 13))         ][hkey].Clone()
            h['BG'] = R.THStack('hBG', '')

        PConfig = {}
        if not MCONLY:
            PConfig['Data'] = ('DoubleMuon2016', 'pe', 'pe')
        if True:
            #           PConfig['Signal'] = ('H#rightarrow2X#rightarrow4#mu', 'l' , 'hist')
            PConfig['BG'] = ('', '', 'hist')

        PC = HistogramGetter.PLOTCONFIG

        for key in BGORDER:
            h[key] = HISTS[key][hkey].Clone()
            RT.addFlows(h[key])
            if h[key].GetNbinsX() > 100: h[key].Rebin(10)
            h[key].Scale(PC[key]['WEIGHT'])
            PConfig[key] = (PC[key]['LATEX'], 'f', 'hist')
            h['BG'].Add(h[key])

        if not MCONLY:
            for era in ('C', 'D', 'E', 'F', 'G', 'H'):
                h['Data'].Add(
                    HISTS['DoubleMuonRun2016{}-07Aug17'.format(era)][hkey])
            RT.addFlows(h['Data'])
            if h['Data'].GetNbinsX() > 100: h['Data'].Rebin(10)

        p = {}
        for key in h:
            p[key] = Plotter.Plot(h[key], *PConfig[key])

        fname = 'pdfs/{}{}_Stack{}{}{}.pdf'.format(hkey, CUTSTRING,
                                                   'MC' if MCONLY else '',
                                                   '-Log' if logy else '',
                                                   '-Rat' if DataMC else '')

        for key in BGORDER:
            p[key].setColor(PC[key]['COLOR'], which='LF')

        canvas = Plotter.Canvas(ratioFactor=0. if not DataMC else 1. / 3.,
                                logy=logy,
                                fontscale=1. if not DataMC else 1. + 1. / 3.)
        if True:
            canvas.addMainPlot(p['BG'])
        if not MCONLY:
            canvas.addMainPlot(p['Data'])
#       canvas.addMainPlot(p['Signal'])

        canvas.makeLegend(lWidth=.27,
                          pos='tr',
                          autoOrder=False,
                          fontscale=0.8 if not DataMC else 1.)
        if not MCONLY:
            canvas.addLegendEntry(p['Data'])
        for key in reversed(BGORDER):
            canvas.addLegendEntry(p[key])
#       canvas.addLegendEntry(p['Signal'])
        canvas.legend.resizeHeight()

        p['BG'].setTitles(X=p['WJets'].GetXaxis().GetTitle(),
                          Y='Normalized Counts')
        RT.addBinWidth(p['BG'])

        canvas.firstPlot.SetMaximum(h['BG'].GetStack().Last().GetMaximum() *
                                    1.05)
        #canvas.firstPlot.SetMaximum(1.e-4)
        if logy:
            canvas.firstPlot.SetMinimum(1.)

        if DataMC:
            canvas.makeRatioPlot(p['Data'].plot,
                                 p['BG'].plot.GetStack().Last())
            canvas.firstPlot.scaleTitleOffsets(0.8, axes='Y')
            canvas.rat.scaleTitleOffsets(0.8, axes='Y')

#       p['Signal'    ].SetLineStyle(2)
#       p['Signal'    ].SetLineColor(R.kRed)

        canvas.finishCanvas(extrascale=1. if not DataMC else 1. + 1. / 3.)
        canvas.save(fname)
        canvas.deleteCanvas()
def makePerSamplePlots(selection=None):
    rebinning_exceptions = ("pTdiff", "nCSCDTHits")

    h = {}
    p = {}
    for dataset in HISTS:
        if selection is not None:
            selected_hists_names = getHistNames(dataset, *selection)
        else:
            selected_hists_names = HISTS[dataset]

        for key in selected_hists_names:

            # do not plot empty histograms in the interest of plotting time
            if HISTS[dataset][key].GetEntries() == 0:
                continue

            if key not in h:
                h[key] = HISTS[dataset][key].Clone()
            else:
                h[key].Add(HISTS[dataset][key])

    for key in h:
        RT.addFlows(h[key])
        if h[key].GetNbinsX() >= 1000:
            if any(["__" + var + "VAR" in key for var in rebinning_exceptions]):
                print ("Do not rebin {}".format(key))
                pass
            else:
                if "__L1pTresVAR" in key or "__L2pTresVAR" in key:
                    h[key].Rebin(2)
                else:
                    h[key].Rebin(15)
        elif h[key].GetNbinsX() >= 100:
            if any(["__" + var + "VAR" in key for var in rebinning_exceptions]):
                print ("Do not rebin {}".format(key))
                pass
            else:
                h[key].Rebin(5)
        else:
            pass

        if "lowerHemisphere" in key:
            hs_req = "lower hemisphere"
        elif "upperHemisphere" in key:
            hs_req = "upper hemisphere"
        else:
            hs_req = None

        if "oppositeCharges" in key:
            pair_charge_req = "oppositely charged pairs"
        elif "equalCharges" in key:
            pair_charge_req = "equally charged pairs"
        else:
            pair_charge_req = None

        if "posCharge" in key:
            charge_req = "positive muon tracks"
        elif "negCharge" in key:
            charge_req = "negative muon tracks"
        else:
            charge_req = None

        legName = ""
        for req in (hs_req, pair_charge_req, charge_req):
            if req is not None:
                if legName != "":
                    legName += ", "
                legName += req

        p = Plotter.Plot(h[key], legName, "l", "hist")

        for is_logy in (True, False):
            fname = "pdfs/{}{}{}.pdf".format(
                key, dataset_fname, ("_logy" if is_logy else "")
            )

            canvas = Plotter.Canvas(logy=is_logy, lumi=lumi)
            canvas.addMainPlot(p)
            if legName != "":
                canvas.makeLegend(lWidth=0.25, pos="tl", fontscale=0.65)
                canvas.legend.resizeHeight()

            for var in RANGES:
                if "__{}VAR".format(var) in key:
                    canvas.firstPlot.GetXaxis().SetRangeUser(
                        RANGES[var][0], RANGES[var][1]
                    )

            p.SetLineColor(R.kBlue)
            RT.addBinWidth(p)

            # Gauss fit for L2 resolution plots
            if any(
                ["__{}VAR".format(var) in key for var in L1RESOLUTIONVARIABLES]
            ) or any(["__{}VAR".format(var) in key for var in L2RESOLUTIONVARIABLES]):

                # Trigger information for canvas
                pave_triggerinfo = R.TPaveText(0.56, 0.38, 0.88, 0.51, "NDCNB")
                pave_triggerinfo.SetTextAlign(13)
                pave_triggerinfo.SetTextFont(42)
                # pave_triggerinfo.SetTextSize(self.fontsize*.9)
                pave_triggerinfo.SetMargin(0)
                pave_triggerinfo.SetFillStyle(0)
                pave_triggerinfo.SetFillColor(0)
                pave_triggerinfo.SetLineStyle(0)
                pave_triggerinfo.SetLineColor(0)
                pave_triggerinfo.SetBorderSize(0)
                pave_triggerinfo.AddText(0.0, 1.0, HLT_info)
                pave_triggerinfo.AddText(0.0, 0.5, L1T_info)
                pave_triggerinfo.Draw()

                fit_xmin, fit_xmax = findFitRange(h[key])
                func = R.TF1("f" + key, "gaus", fit_xmin, fit_xmax)
                func.SetParameters(10.0, -0.1, 0.5)
                func.SetLineStyle(2)
                func.SetLineColor(R.kBlue + 2)
                R.SetOwnership(func, 0)
                h[key].Fit("f" + key, "RQN")
                func.Draw("same")

                pave_gaus = R.TPaveText(0.56, 0.63, 0.88, 0.83, "NDCNB")
                pave_gaus.SetTextAlign(13)
                pave_gaus.SetTextFont(42)
                # pave_gaus.SetTextSize(self.fontsize*.9)
                pave_gaus.SetMargin(0)
                pave_gaus.SetFillStyle(0)
                pave_gaus.SetFillColor(0)
                pave_gaus.SetLineStyle(0)
                pave_gaus.SetLineColor(0)
                pave_gaus.SetBorderSize(0)
                pave_gaus.AddText(0.0, 1.0, "Gaussian fit around maximum:")
                pave_gaus.AddText(
                    0.06, 0.65, "Mean = {:2.3f}".format(func.GetParameter(1))
                )
                pave_gaus.AddText(
                    0.06, 0.45, "Sigma = {:2.3f}".format(func.GetParameter(2))
                )
                pave_gaus.AddText(
                    0.06, 0.25, "#chi^{{2}} = {:2.3f}".format(func.GetChisquare())
                )

                # count the histogram contents to the right of the upper
                # fit limit (to get an estimate for the content in the tail)
                h_content = 0
                h_content_tail = 0
                fit_xmax_bin = h[key].FindBin(fit_xmax)
                for b in range(1, h[key].GetNbinsX() + 1):
                    h_content += h[key].GetBinContent(b)
                    if b > fit_xmax_bin:
                        h_content_tail += h[key].GetBinContent(b)

                pave_gaus.AddText(
                    0.06,
                    0.05,
                    "Entries above {:2.2f} (max. fit range): {:2.1f}%".format(
                        fit_xmax, 100.0 * h_content_tail / h_content
                    ),
                )
                pave_gaus.Draw()

                try:
                    canvas.legend.moveLegend(X=0.393, Y=-0.01)
                except:
                    # continue if there is no legend
                    pass
            else:
                # Trigger information for canvas
                pave_triggerinfo = R.TPaveText(0.4, 0.75, 0.72, 0.88, "NDCNB")
                pave_triggerinfo.SetTextAlign(13)
                pave_triggerinfo.SetTextFont(42)
                # pave_triggerinfo.SetTextSize(self.fontsize*.9)
                pave_triggerinfo.SetMargin(0)
                pave_triggerinfo.SetFillStyle(0)
                pave_triggerinfo.SetFillColor(0)
                pave_triggerinfo.SetLineStyle(0)
                pave_triggerinfo.SetLineColor(0)
                pave_triggerinfo.SetBorderSize(0)
                pave_triggerinfo.AddText(0.0, 1.0, HLT_info)
                pave_triggerinfo.AddText(0.0, 0.5, L1T_info)
                pave_triggerinfo.Draw()

                pave = canvas.makeStatsBox(p, color=R.kBlue)

            pave_triggerinfo.Draw()

            # find the corresponding d0 distribution in the given d0 bin
            # and display its mean
            try:
                current_var = re.findall(r"__(.+)VAR", key)
                if len(current_var) == 1:
                    current_var = current_var[0].split("_")[-1]
                    if current_var != "d0" and all(
                        [c in key for c in ("__d0GT", "__d0LT")]
                    ):
                        d0_hist = key.replace("__{}VAR".format(current_var), "__d0VAR")
                        for idataset, dataset in enumerate(HISTS):
                            if idataset == 0:
                                h_d0 = HISTS[dataset][d0_hist].Clone()
                            else:
                                h_d0.Add(HISTS[dataset][d0_hist])

                        d0_mean = h_d0.GetMean()
                        # d0_mean = HISTS[dataset][d0_hist].GetMean()

                        d0_min = re.findall(r"__d0GT(\d+)p(\d+)", d0_hist)
                        if len(d0_min) > 0:
                            d0_min = float("{}.{}".format(d0_min[0][0], d0_min[0][1]))
                        else:
                            d0_min = float(re.findall(r"__d0GT(\d+)", d0_hist)[0])

                        d0_max = re.findall(r"__d0LT(\d+)p(\d+)", d0_hist)
                        if len(d0_max) > 0:
                            d0_max = float("{}.{}".format(d0_max[0][0], d0_max[0][1]))
                        else:
                            d0_max = float(re.findall(r"__d0LT(\d+)", d0_hist)[0])

                        pave_d0info = R.TPaveText(0.56, 0.53, 0.88, 0.61, "NDCNB")
                        pave_d0info.SetTextAlign(13)
                        pave_d0info.SetTextFont(42)
                        pave_d0info.SetMargin(0)
                        pave_d0info.SetFillStyle(0)
                        pave_d0info.SetFillColor(0)
                        pave_d0info.SetLineStyle(0)
                        pave_d0info.SetLineColor(0)
                        pave_d0info.SetBorderSize(0)
                        pave_d0info.AddText(
                            0.0, 1.0, "{} cm < d_{{0}} < {} cm".format(d0_min, d0_max)
                        )
                        pave_d0info.AddText(
                            0.0, 0.0, "#LTd_{{0}}#GT = {:4.3f} cm".format(d0_mean)
                        )
                        pave_d0info.Draw()
            except KeyError:
                # not all of the histograms have d0 equivalents (e.g.,
                # 'oppositeCharges' pair histos,...)
                print (
                    "[PLOTTER WARNING] Error processing d0 information "
                    "for {}; will not be printed on canvas".format(key)
                )

            canvas.cleanup(fname)

    return
def makeStackPlots(DataMC=False, logy=False):
    BGORDER = ('WJets', 'WW', 'WZ', 'ZZ', 'tW', 'tbarW', 'ttbar', 'DY10to50',
               'DY50toInf')
    for hkey in HISTS['DY50toInf']:

        h = {
            #           'Data'       : HISTS['DoubleMuonRun2016D-07Aug17'][hkey].Clone(),
            #           'Signal'     : HISTS[('4Mu', (125, 20, 13))      ][hkey].Clone(),
            'BG': R.THStack('hBG', '')
        }

        PConfig = {
            #           'Data'       : ('DoubleMuon2016D'              , 'pe', 'pe'  ),
            #           'Signal'     : ('H#rightarrow2X#rightarrow4#mu', 'l' , 'hist'),
            'BG': ('', '', 'hist'),
        }

        PC = HistogramGetter.PLOTCONFIG

        for key in BGORDER:
            h[key] = HISTS[key][hkey].Clone()
            RT.addFlows(h[key])
            if h[key].GetNbinsX() > 100: h[key].Rebin(10)
            h[key].Scale(PC[key]['WEIGHT'])
            PConfig[key] = (PC[key]['LATEX'], 'f', 'hist')
            h['BG'].Add(h[key])

        p = {}
        for key in h:
            p[key] = Plotter.Plot(h[key], *PConfig[key])

        fname = 'pdfs/NM1_{}_Stack{}.pdf'.format(hkey, '-Log' if logy else '')

        for key in BGORDER:
            p[key].setColor(PC[key]['COLOR'], which='LF')

        canvas = Plotter.Canvas(ratioFactor=0. if not DataMC else 1. / 3.,
                                cHeight=600 if not DataMC else 800,
                                logy=logy)
        canvas.addMainPlot(p['BG'])
        #       canvas.addMainPlot(p['Data'])
        #       canvas.addMainPlot(p['Signal'])

        canvas.lumi += ' : |#Delta#Phi| ' + ('<' if '_Less' in key else
                                             '>') + ' #pi/2'

        canvas.makeLegend(lWidth=.27, pos='tr', autoOrder=False, fontscale=0.8)
        #       canvas.addLegendEntry(p['Data'     ])
        for key in reversed(BGORDER):
            canvas.addLegendEntry(p[key])


#       canvas.addLegendEntry(p['Signal'])
        canvas.legend.resizeHeight()

        p['BG'].setTitles(X=p['WJets'].GetXaxis().GetTitle(),
                          Y='Normalized Counts')
        RT.addBinWidth(p['BG'])

        canvas.firstPlot.SetMaximum(h['BG'].GetStack().Last().GetMaximum() *
                                    1.05)
        #canvas.firstPlot.SetMaximum(1.e-4)

        #       if DataMC:
        #           canvas.makeRatioPlot(p['Data'].plot, p['BG'].plot.GetStack().Last())

        #       p['Signal'    ].SetLineStyle(2)
        #       p['Signal'    ].SetLineColor(R.kRed)

        canvas.cleanup(fname)
def makeCombinedPlots(categories, selection=None, exclude=None, logic="and"):
    rebinning_exceptions = ("nCSCDTHits",)

    h = {}
    p = {}

    # import all relevant histograms
    for dataset in HISTS:
        if selection and exclude:
            selected_hists_names = getHistNames(
                dataset, *selection, exclude=exclude, logic=logic
            )
        elif selection and not exclude:
            selected_hists_names = getHistNames(dataset, *selection, logic=logic)
        elif not selection and exclude:
            selected_hists_names = getHistNames(
                dataset, "", exclude=exclude, logic=logic
            )
        else:
            selected_hists_names = HISTS[dataset]

        for key in selected_hists_names:
            if not any([cat in key for cat, __ in categories]):
                continue

            search_res = re.search(r"__(.+)VAR", key)
            if search_res:
                variable = search_res.group(1)
            else:
                print ("Skipping {} (unidentifiable variable)...".format(key))
                continue

            if variable not in h.keys():
                h[variable] = {}

            for category, __ in categories:
                if not category in key:
                    continue

                if category in h[variable]:
                    h[variable][category].Add(HISTS[dataset][key])
                else:
                    h[variable][category] = HISTS[dataset][key].Clone()

    # prepare the histograms
    for variable in h:
        for category in h[variable]:
            RT.addFlows(h[variable][category])

            if h[variable][category].GetNbinsX() >= 1000:
                if variable in rebinning_exceptions:
                    print ("Do not rebin for variable {}".format(variable))
                    pass
                else:
                    h[variable][category].Rebin(15)

            elif h[variable][category].GetNbinsX() >= 100:
                if variable in rebinning_exceptions:
                    print ("Do not rebin for variable {}".format(variable))
                    pass
                else:
                    h[variable][category].Rebin(5)

            else:
                pass

    # start creating plots
    for variable in h:
        p[variable] = {}

        # find the best vertical axes ranges
        realmin = float("inf")
        realmax = -float("inf")

        for category, category_name in categories:
            p[variable][category] = Plotter.Plot(
                h[variable][category], category_name, "l", "hist"
            )

            key_fname = h[variable][category].GetName()
            key_fname = key_fname.replace(category, "")
            if len(HISTS.keys()) > 1:
                search_res = re.search(r"(_*?NoBPTXRun\d+[A-Z][_-]07Aug17)", key_fname)
                if search_res:
                    key_fname = key_fname.replace(search_res.group(0), "")
                else:
                    print (
                        "Could not identify datset. Dataset name will not be "
                        "stripped from the output file names"
                    )

            if p[variable][category].GetMaximum() > realmax:
                realmax = p[variable][category].GetMaximum()

            if p[variable][category].GetMaximum() < realmin:
                realmin = p[variable][category].GetMinimum()

        for is_logy in (True, False):
            palette = Plotter.ColorPalette([867, 417, 600, 600, 801, 632])
            fname = "pdfs/comb_{}{}.pdf".format(key_fname, ("_logy" if is_logy else ""))
            canvas = Plotter.Canvas(logy=is_logy, lumi="NoBPTXRun2016[D+E]-07Aug17")
            for category, category_name in categories:
                canvas.addMainPlot(p[variable][category])
                p[variable][category].SetLineColor(palette.getNextColor())
                if "goodQuality" in category:
                    p[variable][category].SetLineStyle(2)

                RT.addBinWidth(p[variable][category])

            if variable in RANGES:
                canvas.firstPlot.GetXaxis().SetRangeUser(
                    RANGES[variable][0], RANGES[variable][1]
                )

            canvas.makeLegend(lWidth=0.3, pos="tr", fontscale=0.65)
            canvas.legend.resizeHeight()
            canvas.legend.moveLegend(X=-0.2, Y=-0.13)

            # trigger information for canvas
            pave_triggerinfo = R.TPaveText(0.4, 0.75, 0.72, 0.88, "NDCNB")
            pave_triggerinfo.SetTextAlign(13)
            pave_triggerinfo.SetTextFont(42)
            # pave_triggerinfo.SetTextSize(self.fontsize*.9)
            pave_triggerinfo.SetMargin(0)
            pave_triggerinfo.SetFillStyle(0)
            pave_triggerinfo.SetFillColor(0)
            pave_triggerinfo.SetLineStyle(0)
            pave_triggerinfo.SetLineColor(0)
            pave_triggerinfo.SetBorderSize(0)
            pave_triggerinfo.AddText(0.0, 1.0, HLT_info)
            pave_triggerinfo.AddText(0.0, 0.5, L1T_info)
            pave_triggerinfo.Draw()

            if is_logy and realmin == 0:
                realmin = 0.5
            canvas.firstPlot.GetYaxis().SetRangeUser(realmin * 0.8, realmax * 1.2)

            # canvas.cleanup(fname.replace('.pdf','.root'))
            canvas.cleanup(fname)