Example #1
0
def draw_hists(hists,
               field,
               category,
               textsize=22,
               logy=False,
               unit_area=False):

    xtitle = get_xtitle(field)

    c = Canvas()
    c.SetGridx()
    c.SetGridy()
    c.SetLogy(logy)

    if not isinstance(hists, (list, tuple)):
        hists = [hists]

    if unit_area:
        for h in hists:
            if h.integral() != 0:
                h /= h.integral()

    hists[0].xaxis.title = xtitle
    hists[0].yaxis.title = 'Arbitrary Unit'

    y_max = get_ymax(hists)
    hists[0].yaxis.SetRangeUser(0., 1.05 * y_max)
    hists[0].Draw('HIST')

    colors = [
        'black',
        'red',
        'orange',
        'blue',
        'green',
        'purple',
        'yellow',
        'pink',
    ]
    if len(hists) > len(colors):
        colors = len(hists) * colors
    for hist, col in zip(hists, colors):
        hist.color = col
        hist.color = col
        hist.fillstyle = 'hollow'
        hist.markersize = 0
        hist.linewidth = 2
        hist.linestyle = 'solid'
        hist.drawstyle = 'hist E0'
        hist.legendstyle = 'l'
        hist.Draw('SAMEHIST')
    label = ROOT.TLatex(c.GetLeftMargin() + 0.04, 0.9, category.label)
    label.SetNDC()
    label.SetTextFont(43)
    label.SetTextSize(textsize)
    label.Draw()
    leg = Legend(hists, pad=c, textsize=20)
    # textsize=20, leftmargin=0.6, topmargin=0.6)
    leg.Draw('same')
    return c
Example #2
0
def plot(params, rates):
    canvas = Canvas(width=500, height=500)
    draw_axes(params)
    draw_rates(params, rates)
    HGCAL_label(text='HGCAL Simulation', pad=canvas)
    canvas.SetLogy()
    canvas.RedrawAxis()
    canvas.Print('%s.png' % params.name)
    canvas.Print('%s.pdf' % params.name)
    canvas.Print('%s.C' % params.name)
Example #3
0
                                                  markercolor='blue')

uct_iso_efficiency = Efficiency(uct_iso_pass_vs_pu,
                                total_vs_pu).decorate(linecolor='green',
                                                      linewidth=2,
                                                      markerstyle=20,
                                                      markercolor='green')

frame = Hist(*binning)

frame.SetMaximum(1)
frame.SetMinimum(0)
frame.axis().SetTitle("Number of vertices")
frame.axis(2).SetTitle("Efficiency (w.r.t. reco. p_{T}>40 GeV)")

canvas.SetLogy(False)
canvas.SetLeftMargin(0.2)

frame.Draw()
l1_efficiency.Draw('pe same')
uct_efficiency.Draw('pe same')
uct_iso_efficiency.Draw('pe same')

legend = Legend(3, topmargin=0.25, leftmargin=0.25)
legend.AddEntry(l1_efficiency, 'lp', 'Current Tau44')
legend.AddEntry(uct_efficiency, 'lp',
                'Upgrade RlxTau25 Rel. Rate %0.2f' % (9488. / 9355))
legend.AddEntry(uct_iso_efficiency, 'lp',
                'Upgrade IsoTau25 Rel. Rate %0.2f' % (6224. / 9355))
legend.SetBorderSize(0)
legend.SetTextSize(0.03)
Example #4
0
dn.Draw('same hist')

leg = Legend(3, pad=canvas, leftmargin=.5)
leg.AddEntry(nominal, style='LEP')
leg.AddEntry(up, style='L')
leg.AddEntry(dn, style='L')
leg.Draw()
canvas.SaveAs('canvas_original.png')

# Take the ratio of systematic / nominal

ratio_up = up / nominal
ratio_dn = dn / nominal

ratio_canvas = Canvas()
ratio_canvas.SetLogy()
ratio_up.SetMinimum(0.001)
ratio_up.Draw('hist')
ratio_dn.Draw('same hist')
ratio_up.xaxis.SetTitle('BDT Score')
ratio_up.yaxis.SetTitle('Systematic / Nominal')
ratio_canvas.SaveAs('canvas_ratio.png')

# Now smooth each ratio

ratio_up_smooth = ratio_up.Clone()
ratio_up_smooth.Smooth(args.smooth_iterations)
ratio_dn_smooth = ratio_dn.Clone()
ratio_dn_smooth.Smooth(args.smooth_iterations)

ratio_smooth_canvas = Canvas()
Example #5
0
def mpe_fitting(filename, run, num_photons, use_ideal=True):

    run_number = int(run)

    if filename[-5:] == '.root':
        filename = filename[:-5]

    s_data_path = './data/%s.p' % filename

    if filename[:5] == 'nerix':
        file_identifier = filename
    else:
        file_identifier = filename[-9:]

    a_integral = pickle.load((open(s_data_path, 'r')))

    # max_num_events used to limit amplitudes
    max_num_events = len(a_integral)

    s_path_to_save = './results/%s/' % (file_identifier)
    l_colors = [4, 2, 8, 7, 5, 9] + [4, 2, 8, 7, 5, 9]

    d_mpe_fit = {}

    if file_identifier == '0062_0061':
        d_mpe_fit['settings'] = [250, -1e6, 2e7]

        d_mpe_fit['bkg_mean_low'] = -1e6
        d_mpe_fit['bkg_mean_high'] = 2e6
        d_mpe_fit['bkg_width_low'] = 1e4
        d_mpe_fit['bkg_width_high'] = 1e6
        d_mpe_fit['spe_mean_low'] = 3.5e6
        d_mpe_fit['spe_mean_high'] = 1e7
        d_mpe_fit['spe_width_low'] = 8e5
        d_mpe_fit['spe_width_high'] = 3e6
        d_mpe_fit['ua_mean_low'] = 1e5
        d_mpe_fit['ua_mean_high'] = 5e6
        d_mpe_fit['ua_width_low'] = 1e4
        d_mpe_fit['ua_width_high'] = 1e6

        d_mpe_fit['spe_mean_guess'] = 6e6
        d_mpe_fit['spe_width_guess'] = 1.9e6
    
    elif file_identifier == '0066_0065':
        d_mpe_fit['settings'] = [250, -1e6, 1.2e7]

        d_mpe_fit['bkg_mean_low'] = -1e6
        d_mpe_fit['bkg_mean_high'] = 2e6
        d_mpe_fit['bkg_width_low'] = 1e4
        d_mpe_fit['bkg_width_high'] = 1e6
        d_mpe_fit['spe_mean_low'] = 2e6
        d_mpe_fit['spe_mean_high'] = 6e6
        d_mpe_fit['spe_width_low'] = 8e5
        d_mpe_fit['spe_width_high'] = 3e6
        d_mpe_fit['ua_mean_low'] = 1e5
        d_mpe_fit['ua_mean_high'] = 5e6
        d_mpe_fit['ua_width_low'] = 1e4
        d_mpe_fit['ua_width_high'] = 1e6

        d_mpe_fit['spe_mean_guess'] = 3.6e6
        d_mpe_fit['spe_width_guess'] = 1.1e6

    elif file_identifier == '0067_0068':
        d_mpe_fit['settings'] = [250, -1e6, 7.5e6]

        d_mpe_fit['bkg_mean_low'] = -5e5
        d_mpe_fit['bkg_mean_high'] = 5e5
        d_mpe_fit['bkg_width_low'] = 1e4
        d_mpe_fit['bkg_width_high'] = 1e6
        d_mpe_fit['spe_mean_low'] = 1.2e6
        d_mpe_fit['spe_mean_high'] = 3.5e6
        d_mpe_fit['spe_width_low'] = 3e5
        d_mpe_fit['spe_width_high'] = 1e6
        d_mpe_fit['ua_mean_low'] = 1e5
        d_mpe_fit['ua_mean_high'] = 1.5e6
        d_mpe_fit['ua_width_low'] = 1e4
        d_mpe_fit['ua_width_high'] = 1e6

        d_mpe_fit['spe_mean_guess'] = 2.1e6
        d_mpe_fit['spe_width_guess'] = 6.6e5

    elif file_identifier == '0071_0072':
        d_mpe_fit['settings'] = [250, -1e6, 3.4e7]

        d_mpe_fit['bkg_mean_low'] = -1e6
        d_mpe_fit['bkg_mean_high'] = 2e6
        d_mpe_fit['bkg_width_low'] = 1e4
        d_mpe_fit['bkg_width_high'] = 1e6
        d_mpe_fit['spe_mean_low'] = 7.5e6
        d_mpe_fit['spe_mean_high'] = 1.4e7
        d_mpe_fit['spe_width_low'] = 1e6
        d_mpe_fit['spe_width_high'] = 3.5e6
        d_mpe_fit['ua_mean_low'] = 1e5
        d_mpe_fit['ua_mean_high'] = 5e6
        d_mpe_fit['ua_width_low'] = 1e4
        d_mpe_fit['ua_width_high'] = 1e6

        d_mpe_fit['spe_mean_guess'] = 9.5e6
        d_mpe_fit['spe_width_guess'] = 2.9e6

    elif file_identifier == '0073_0074':
        d_mpe_fit['settings'] = [50, -1e6, 4.2e7]

        d_mpe_fit['bkg_mean_low'] = -1e6
        d_mpe_fit['bkg_mean_high'] = 2e6
        d_mpe_fit['bkg_width_low'] = 1e5
        d_mpe_fit['bkg_width_high'] = 2e6
        d_mpe_fit['spe_mean_low'] = 8.5e6
        d_mpe_fit['spe_mean_high'] = 1.4e7
        d_mpe_fit['spe_width_low'] = 1.5e6
        d_mpe_fit['spe_width_high'] = 4.5e6
        d_mpe_fit['ua_mean_low'] = 5e5
        d_mpe_fit['ua_mean_high'] = 4e6
        d_mpe_fit['ua_width_low'] = 0.5e6
        d_mpe_fit['ua_width_high'] = 1e6

        d_mpe_fit['spe_mean_guess'] = 9.5e6
        d_mpe_fit['spe_width_guess'] = 2.9e6

    elif file_identifier == 'nerix_160418_1523':
        d_mpe_fit['settings'] = [50, -5e5, 3.e6]
        
        d_mpe_fit['bkg_mean_low'] = -5e5
        d_mpe_fit['bkg_mean_high'] = 5e5
        d_mpe_fit['bkg_width_low'] = 1e4
        d_mpe_fit['bkg_width_high'] = 5e5
        d_mpe_fit['spe_mean_low'] = 6e5
        d_mpe_fit['spe_mean_high'] = 11e5
        d_mpe_fit['spe_width_low'] = 3e5
        d_mpe_fit['spe_width_high'] = 9e5
        d_mpe_fit['ua_mean_low'] = 1e3
        d_mpe_fit['ua_mean_high'] = 5e5
        d_mpe_fit['ua_width_low'] = 1e4
        d_mpe_fit['ua_width_high'] = 5e5

    elif file_identifier == 'nerix_160418_1531':
        d_mpe_fit['settings'] = [50, -5e5, 4.e6]
        
        d_mpe_fit['bkg_mean_low'] = -5e5
        d_mpe_fit['bkg_mean_high'] = 5e5
        d_mpe_fit['bkg_width_low'] = 1e4
        d_mpe_fit['bkg_width_high'] = 5e5
        d_mpe_fit['spe_mean_low'] = 6e5
        d_mpe_fit['spe_mean_high'] = 11e5
        d_mpe_fit['spe_width_low'] = 3e5
        d_mpe_fit['spe_width_high'] = 9e5
        d_mpe_fit['ua_mean_low'] = 1e3
        d_mpe_fit['ua_mean_high'] = 5e5
        d_mpe_fit['ua_width_low'] = 1e4
        d_mpe_fit['ua_width_high'] = 5e5

    else:
        print '\n\nSettings do not exist for given setup: %s\n\n' % (file_identifier)
        sys.exit()

    l_plots = ['plots', file_identifier]


    par_names = ['p0_ampl', 'mean_bkg', 'width_bkg', 'mean_spe', 'width_spe'] + ['p%d_ampl' % (i + 1) for i in xrange(num_photons)]




    a_integral = pickle.load((open(s_data_path, 'r')))

    if use_ideal:
        l_mpe_fit_func = ['[5]/(2*3.14*%d*[4]**2.)**0.5*TMath::Poisson(%d, [0])*exp(-0.5/%.1f*((x - %.1f*[3])/[4])**2)' % (iElectron, iElectron, iElectron, iElectron) for iElectron in xrange(1, num_photons + 1)]
    else:
        l_mpe_fit_func = ['[5]/(2*3.14*([2]**2. + %d*[4]**2.))**0.5*TMath::Poisson(%d, [0])*exp(-0.5*((x - %.1f*[3] - [1])/(%.1f*[4]**2 + [2]**2)**0.5)**2)' % (iElectron, iElectron, iElectron, iElectron) for iElectron in xrange(1, num_photons + 1)]

    h_mpe_spec = Hist(*d_mpe_fit['settings'], name='h_mpe_spec', title='MPE Spectrum with Gaussian Fit - %s' % filename)
    h_mpe_spec.SetMarkerSize(0)
    h_mpe_spec.fill_array(a_integral)

    c1 = Canvas()

    h_mpe_spec.Draw()

    s_bkg = '[5]/(2*3.14*[2]**2.)**0.5*TMath::Poisson(0, [0])*exp(-0.5*((x - [1])/[2])**2)'
    s_under_amplified = '[6]/(2*3.14*[8]**2.)**0.5*exp(-0.5*((x - [7])/[8])**2)'
    s_fit_mpe = '(%s) + (%s) + (%s)' % (s_bkg, s_under_amplified, ' + '.join(l_mpe_fit_func))
    s_fit_mpe = '(%s)*([1] < [3] ? 1. : 0.)*([1] < [7] ? 1. : 0.)*([7] < [3] ? 1. : 0.)' % (s_fit_mpe)
    fit_mpe = root.TF1('fit_mpe', s_fit_mpe, *d_mpe_fit['settings'][1:])
    fit_mpe.SetLineColor(46)
    fit_mpe.SetLineStyle(2)
    fit_mpe.SetLineWidth(3)

    h_mpe_spec.GetXaxis().SetTitle('Integrated Charge [e-]')
    h_mpe_spec.GetYaxis().SetTitle('Counts')
    h_mpe_spec.GetYaxis().SetTitleOffset(1.4)
    h_mpe_spec.SetStats(0)

    c1.SetLogy()


    fit_mpe.SetParLimits(0, 0.9, 2.5)
    fit_mpe.SetParameter(0, 1.3)
    fit_mpe.SetParLimits(1, d_mpe_fit['bkg_mean_low'], d_mpe_fit['bkg_mean_high'])
    fit_mpe.SetParameter(1, (d_mpe_fit['bkg_mean_low']+d_mpe_fit['bkg_mean_high'])/2.)
    fit_mpe.SetParLimits(2, d_mpe_fit['bkg_width_low'], d_mpe_fit['bkg_width_high'])
    fit_mpe.SetParameter(2, (d_mpe_fit['bkg_width_low']+d_mpe_fit['bkg_width_high'])/2.)
    fit_mpe.SetParLimits(3, d_mpe_fit['spe_mean_low'], d_mpe_fit['spe_mean_high'])
    fit_mpe.SetParameter(3, d_mpe_fit['spe_mean_guess'])
    fit_mpe.SetParLimits(4, d_mpe_fit['spe_width_low'], d_mpe_fit['spe_width_high'])
    fit_mpe.SetParameter(4, d_mpe_fit['spe_width_guess'])
    fit_mpe.SetParLimits(5, 10, max_num_events*1e6)
    fit_mpe.SetParameter(5, (10+max_num_events*1e6)/2.)
    fit_mpe.SetParLimits(6, 10, max_num_events*1e6)
    fit_mpe.SetParameter(6, (10+max_num_events*1e6)/2.)
    fit_mpe.SetParLimits(7, d_mpe_fit['ua_mean_low'], d_mpe_fit['ua_mean_high'])
    fit_mpe.SetParameter(7, (d_mpe_fit['ua_mean_low']+d_mpe_fit['ua_mean_high'])/2.)
    fit_mpe.SetParLimits(8, d_mpe_fit['ua_width_low'], d_mpe_fit['ua_width_high'])
    fit_mpe.SetParameter(8, (d_mpe_fit['ua_width_low']+d_mpe_fit['ua_width_high'])/2.)


    """
    for i, guess in enumerate(mpe_par_guesses):
        fit_mpe.SetParameter(i, guess)

    for i in xrange(len(par_names)):
        fit_mpe.SetParName(i, par_names[i])


    for photon in xrange(num_photons):
        fit_mpe.SetParLimits(5 + photon, 0, max_num_events)
    """

    fitResult = h_mpe_spec.Fit('fit_mpe', 'MILES')



    # draw individual peaks
    s_gaussian = '[0]*exp(-0.5/%.1f*((x - %.1f*[1])/[2])**2)'
    l_functions = []
    l_individual_integrals = [0. for i in xrange(num_photons+2)]
    for i in xrange(num_photons + 2):
        l_functions.append(root.TF1('peak_%d' % i, '[0]*exp(-0.5*((x - [1])/[2])**2)', *d_mpe_fit['settings'][1:]))

        # set parameters
        if i == 0:
            ampl = fit_mpe.GetParameter(5)*root.TMath.Poisson(0, fit_mpe.GetParameter(0))
            mean = fit_mpe.GetParameter(1)
            width = fit_mpe.GetParameter(2)
            if width > 0:
                ampl /= (2*3.14*width**2.)**0.5
            l_functions[i].SetParameters(ampl, mean, width)
            
        # under amplified peak
        elif i == (num_photons + 1):
            ampl = fit_mpe.GetParameter(6)
            mean = fit_mpe.GetParameter(7)
            width = fit_mpe.GetParameter(8)
            if width > 0:
                ampl /= (2*3.14*width**2.)**0.5
            l_functions[i].SetParameters(ampl, mean, width)

        else:
            ampl = fit_mpe.GetParameter(5)*root.TMath.Poisson(i, fit_mpe.GetParameter(0))
            if use_ideal:
                mean = fit_mpe.GetParameter(3) * i
                width = fit_mpe.GetParameter(4)*i**0.5
            else:
                mean = fit_mpe.GetParameter(3)*i + fit_mpe.GetParameter(1)
                width = (fit_mpe.GetParameter(4)**2*i + fit_mpe.GetParameter(2)**2)**0.5

            if width > 0:
                ampl /= (2*3.14*width**2.)**0.5

            l_functions[i].SetParameters(ampl, mean, width)



        l_individual_integrals[i] = ampl*width*(2*3.1415)**0.5
        l_functions[i].SetLineColor(l_colors[i])
        l_functions[i].Draw('same')




    c1.Update()


    fitStatus = fitResult.CovMatrixStatus()
    if fitStatus != 3:
        neriX_analysis.failure_message('Fit failed, please adjust guesses and try again.')
        fit_successful = False
    else:
        neriX_analysis.success_message('Fit successful, please copy output to appropriate files.')
        fit_successful = True

    #if not os.path.exists(sPathToSaveOutput):
    #    os.makedirs(sPathToSaveOutput)

    fitter = root.TVirtualFitter.Fitter(fit_mpe)
    #fitter = root.TVirtualFitter.GetFitter()
    amin = np.asarray([0], dtype=np.float64)
    dum1 = np.asarray([0], dtype=np.float64)
    dum2 = np.asarray([0], dtype=np.float64)
    dum3 = np.asarray([0], dtype=np.int32)
    dum4 = np.asarray([0], dtype=np.int32)

    fitter.GetStats(amin, dum1, dum2, dum3, dum4)


    print '\n\namin for %d photons: %f' % (num_photons, amin)
    print 'fAmin for %d photons: %f\n\n' % (num_photons, root.gMinuit.fAmin)
    print fit_mpe.GetChisquare()


    # draw tpavetext
    tpt_mpe = root.TPaveText(.55,.75,.85,.85,'blNDC')
    tpt_mpe.AddText('#mu_{SPE} = %.2e #pm %.2e' % (fit_mpe.GetParameter(3), fit_mpe.GetParError(3)))
    tpt_mpe.AddText('#sigma_{SPE} = %.2e #pm %.2e' % (fit_mpe.GetParameter(4), fit_mpe.GetParError(4)))
    tpt_mpe.Draw('same')

    tpt_mpe.SetTextColor(root.kBlack)
    tpt_mpe.SetFillStyle(0)
    tpt_mpe.SetBorderSize(0)

    c1.Update()


    neriX_analysis.save_plot(l_plots, c1, 'mpe_poisson_gaussian_fit_%s' % (file_identifier))


    return (0,0,0)
Example #6
0
# ymax = getMax( [h_data, h_t1After, h_t2After, h_t3After] )
# h_data.GetYaxis().SetRangeUser(0,ymax)
# h_t1After.GetYaxis().SetRangeUser(0,ymax)
# h_t2After.GetYaxis().SetRangeUser(0,ymax)
# h_t3After.GetYaxis().SetRangeUser(0,ymax)

leg.AddEntry(h_tSumAfter, style='L', label='Sum')
leg.Draw()

c.Update()

if drawScancan:
    scancan = Canvas()
    scancan.Divide(nTemplates)
    scancan.SetLogy()
    nCan = 1
    if useT1:
        scancan.cd(nCan)
        #     scan1.SetMaximum(scan1.GetMaximum()/100)
        scan1.SetMarkerStyle(20)
        #     scan1.SetMarkerSize(1)
        scan1.Draw('AP')
        nCan = nCan + 1
        pass
    if useT2:
        scancan.cd(nCan)
        scan2.SetMaximum(1000)
        scan2.SetMarkerStyle(20)
        #     scan2.SetMarkerSize(20)
        scan2.Draw('AP')
Example #7
0
def pvalue_plot(poi,
                pvalues,
                pad=None,
                xtitle='X',
                ytitle='P_{0}',
                linestyle=None,
                linecolor=None,
                yrange=None,
                verbose=False):
    """
    Draw a pvalue plot

    Parameters
    ----------
    poi : list
        List of POI values tested
    pvalues : list
        List of p-values or list of lists of p-values to overlay
        multiple p-value curves
    pad : Canvas or Pad, optional (default=None)
        Pad to draw onto. Create new pad if None.
    xtitle : str, optional (default='X')
        The x-axis label (POI name)
    ytitle : str, optional (default='P_{0}')
        The y-axis label
    linestyle : str or list, optional (default=None)
        Line style for the p-value graph or a list of linestyles for
        multiple p-value graphs.
    linecolor : str or list, optional (default=None)
        Line color for the p-value graph or a list of linestyles for
        multiple p-value graphs.

    Returns
    -------
    pad : Canvas
        The pad.
    graphs : list of Graph
        The p-value graphs

    """
    if not pvalues:
        raise ValueError("pvalues is empty")
    if not poi:
        raise ValueError("poi is empty")
    # determine if pvalues is list or list of lists
    if not isinstance(pvalues[0], (list, tuple)):
        pvalues = [pvalues]
    if linecolor is not None:
        if not isinstance(linecolor, list):
            linecolor = [linecolor]
        linecolor = cycle(linecolor)
    if linestyle is not None:
        if not isinstance(linestyle, list):
            linestyle = [linestyle]
        linestyle = cycle(linestyle)

    with preserve_current_canvas():
        if pad is None:
            pad = Canvas()
        pad.cd()
        pad.SetLogy()

        # create the axis
        min_poi, max_poi = min(poi), max(poi)
        haxis = Hist(1000, min_poi, max_poi)
        xaxis = haxis.xaxis
        yaxis = haxis.yaxis
        xaxis.SetRangeUser(min_poi, max_poi)
        haxis.Draw('AXIS')

        min_pvalue = float('inf')
        graphs = []
        for ipv, pv in enumerate(pvalues):
            graph = Graph(len(poi),
                          linestyle='dashed',
                          drawstyle='L',
                          linewidth=2)
            for idx, (point, pvalue) in enumerate(zip(poi, pv)):
                graph.SetPoint(idx, point, pvalue)
            if linestyle is not None:
                graph.linestyle = linestyle.next()
            if linecolor is not None:
                graph.linecolor = linecolor.next()
            graphs.append(graph)
            curr_min_pvalue = min(pv)
            if curr_min_pvalue < min_pvalue:
                min_pvalue = curr_min_pvalue

        if verbose:
            for graph in graphs:
                log.info(['{0:1.1f}'.format(xval) for xval in list(graph.x())])
                log.info(['{0:0.3f}'.format(yval) for yval in list(graph.y())])

        # automatically handles axis limits
        axes, bounds = draw(graphs,
                            pad=pad,
                            same=True,
                            logy=True,
                            xtitle=xtitle,
                            ytitle=ytitle,
                            xaxis=xaxis,
                            yaxis=yaxis,
                            ypadding=(0.2, 0.1),
                            logy_crop_value=1E-300)

        if yrange is not None:
            xaxis, yaxis = axes
            yaxis.SetLimits(*yrange)
            yaxis.SetRangeUser(*yrange)
            min_pvalue = yrange[0]

        # draw sigma levels up to minimum of pvalues
        line = Line()
        line.SetLineStyle(2)
        line.SetLineColor(2)
        latex = ROOT.TLatex()
        latex.SetNDC(False)
        latex.SetTextSize(20)
        latex.SetTextColor(2)
        sigma = 0
        while True:
            pvalue = gaussian_cdf_c(sigma)
            if pvalue < min_pvalue:
                break
            keepalive(
                pad,
                latex.DrawLatex(max_poi, pvalue, " {0}#sigma".format(sigma)))
            keepalive(pad, line.DrawLine(min_poi, pvalue, max_poi, pvalue))
            sigma += 1

        pad.RedrawAxis()
        pad.Update()
    return pad, graphs
Example #8
0
def stack(x, *args, **kwargs):

    ## parse arguments
    _data = kwargs.pop('data', None)
    _bkgs = kwargs.pop('bkgs', None)
    _sigs = kwargs.pop('sigs', None)
    _treename = kwargs.pop('treename', None)
    _datasearchpath = kwargs.pop('datasearchpath', None)
    _datadrivensearchpath = kwargs.pop('datadrivensearchpath', None)
    _bkgsearchpath = kwargs.pop('bkgsearchpath', None)
    _sigsearchpath = kwargs.pop('sigsearchpath', None)
    _lumi = kwargs.pop('lumi', None)

    global data
    global bkgs
    global sigs
    global treename
    global datasearchpath
    global datadrivensearchpath
    global bkgsearchpath
    global sigsearchpath
    global lumi

    data = _data or data
    bkgs = _bkgs or bkgs
    sigs = _sigs or sigs
    treename = _treename or treename
    datasearchpath = _datasearchpath or datasearchpath
    datadrivensearchpath = _datadrivensearchpath or datadrivensearchpath
    bkgsearchpath = _bkgsearchpath or bkgsearchpath
    sigsearchpath = _sigsearchpath or sigsearchpath
    if _lumi:
        lumi = float(_lumi)

    xtitle = kwargs.pop('xtitle', '')
    ytitle = kwargs.pop('ytitle', '')
    logx = bool(kwargs.pop('logx', False))
    logy = bool(kwargs.pop('logy', False))
    blind = kwargs.pop('blind', None)
    has_blinded_data = False

    ## save stuff to bookkeep and return
    stuff = dict()
    stuff['x'] = x

    ## get data histogram
    h_data = None
    if data:
        sp = datasearchpath  # HACK: just data to True!
        newx = '%s::%s::%s' % (sp, treename, x)
        h_data = ipyhep.tree.project(newx, *args, **kwargs)
        if h_data:
            stuff['h_data'] = h_data

    ## blind the data?
    if h_data and not blind is None:
        if isinstance(blind, tuple):
            blind1, blind2 = blind
            nbins = h_data.GetNbinsX()
            for i_bin in xrange(1, nbins +
                                2):  # skip underflow (but not overflow)
                xval1 = h_data.GetXaxis().GetBinLowEdge(i_bin)
                xval2 = h_data.GetXaxis().GetBinUpEdge(i_bin)
                if xval1 >= blind1 and xval2 <= blind2:
                    h_data.SetBinContent(i_bin, 0.0)
                    h_data.SetBinError(i_bin, 0.0)
                    has_blinded_data = True
        else:
            nbins = h_data.GetNbinsX()
            for i_bin in xrange(1, nbins +
                                2):  # skip underflow (but not overflow)
                xval = h_data.GetXaxis().GetBinLowEdge(i_bin)
                if xval >= blind:
                    h_data.SetBinContent(i_bin, 0.0)
                    h_data.SetBinError(i_bin, 0.0)
                    has_blinded_data = True

    ## get background histograms
    h_bkgs = list()
    n_bkgs = list()
    if bkgs:
        for bkg in bkgs:
            if isinstance(bkg, list):
                h_subtotal = None
                for dsid in bkg:
                    assert isinstance(dsid, str)
                    h_bkg = None
                    if dsid.isdigit():
                        ## mc backgrounds
                        sp = bkgsearchpath % int(dsid)
                        newx = '%s::%s::%s' % (sp, treename, x)
                        h_bkg = ipyhep.tree.project(newx, *args, **kwargs)
                    else:
                        ## data-driven backgrounds
                        assert dsid == 'fakes' or dsid == 'efakes'
                        sp = datadrivensearchpath % dsid
                        newx = '%s::%s::%s' % (sp, treename, x)
                        h_bkg = ipyhep.tree.project(newx, *args, **kwargs)
                    if h_bkg:
                        if h_subtotal:
                            h_subtotal.Add(h_bkg)
                        else:
                            h_subtotal = h_bkg.Clone()
                if h_subtotal:
                    h_bkgs.append(h_subtotal)
                    dsid = bkg[0]
                    n_bkgs.append(dsid)
            else:
                dsid = bkg
                assert isinstance(dsid, str)
                h_bkg = None
                if dsid.isdigit():
                    ## mc backgrounds
                    sp = bkgsearchpath % int(dsid)
                    newx = '%s::%s::%s' % (sp, treename, x)
                    h_bkg = ipyhep.tree.project(newx, *args, **kwargs)
                else:
                    ## data-driven backgrounds
                    assert dsid == 'fakes' or dsid == 'efakes'
                    sp = datadrivensearchpath % dsid
                    newx = '%s::%s::%s' % (sp, treename, x)
                    h_bkg = ipyhep.tree.project(newx, *args, **kwargs)
                if h_bkg:
                    h_bkgs.append(h_bkg)
                    n_bkgs.append(dsid)
        if h_bkgs:
            stuff['h_bkgs'] = h_bkgs

    ## get signal histograms
    h_sigs = list()
    n_sigs = list()
    if sigs:
        for dsid in sigs:
            sp = sigsearchpath % int(dsid)
            newx = '%s::%s::%s' % (sp, treename, x)
            h_sig = ipyhep.tree.project(newx, *args, **kwargs)
            if h_sig:
                h_sigs.append(h_sig)
                n_sigs.append(dsid)
        if h_sigs:
            stuff['h_sigs'] = h_sigs

    assert h_sigs

    ## style data
    if h_data:
        h_data.title = 'Data'
        h_data.linecolor = ipyhep.style.black
        h_data.linewidth = 2
        h_data.markercolor = ipyhep.style.black
        h_data.markerstyle = 20
        h_data.markersize = 1.2
        h_data.fillstyle = ipyhep.style.fill_hollow
        h_data.drawstyle = 'PE'
        h_data.legendstyle = 'LP'

    ## scale and style background histograms
    if h_bkgs:
        assert len(h_bkgs) == len(n_bkgs), '%s\n%s' % (h_bkgs, n_bkgs)

        for h, dsid in zip(h_bkgs, n_bkgs):
            sf = ipyhep.sampleops.get_sf(dsid)
            if dsid.isdigit():
                sf *= lumi / __ntuple_lumi
            h.Scale(sf)

            h.title = ipyhep.sampleops.get_label(dsid)
            h.linecolor = ipyhep.style.black
            h.linewidth = 1
            h.markercolor = ipyhep.sampleops.get_color(dsid)
            h.fillcolor = ipyhep.sampleops.get_color(dsid)
            h.fillstyle = ipyhep.style.fill_solid
            h.legendstyle = 'F'

    ## calculate stat error on total background
    h_bkg_total = None
    if h_bkgs:
        for h_bkg in h_bkgs:
            if h_bkg_total:
                h_bkg_total.Add(h_bkg)
            else:
                h_bkg_total = h_bkg.Clone()
        stuff['h_bkg_total'] = h_bkg_total

    ## style h_bkg_total
    if h_bkg_total:
        h_bkg_total.title = 'stat. uncert.'
        h_bkg_total.linecolor = ipyhep.style.black
        h_bkg_total.linewidth = 1
        h_bkg_total.markerstyle = 0
        h_bkg_total.fillcolor = ipyhep.style.dark_gray
        h_bkg_total.fillstyle = ipyhep.style.fill_lines
        h_bkg_total.drawstyle = 'E2'
        h_bkg_total.legendstyle = 'LF'

    ## scale and style signal histograms
    if h_sigs:
        assert len(h_sigs) == len(n_sigs)
        for h, dsid in zip(h_sigs, n_sigs):
            sf = ipyhep.sampleops.get_sf(dsid)
            sf *= lumi / __ntuple_lumi
            h.Scale(sf)

            h.title = ipyhep.sampleops.get_label(dsid)
            h.linecolor = ipyhep.sampleops.get_color(dsid)
            h.linewidth = 3
            h.fillstyle = ipyhep.style.fill_hollow
            h.markerstyle = 0
            h.drawstyle = 'HIST'
            h.legendstyle = 'L'

    ## build list of all_hists
    all_hists = list()
    main_hists = list()
    if h_data:
        all_hists.append(h_data)
        main_hists.append(h_data)
    if h_bkgs:
        all_hists.extend(h_bkgs)
        main_hists.extend(h_bkgs)
    if h_bkg_total:
        all_hists.append(h_bkg_total)
        main_hists.append(h_bkg_total)
    if h_sigs:
        all_hists.extend(h_sigs)

    ## get statistics
    if all_hists:
        stats_list = list()
        for h in all_hists:
            stats_list.extend(get_stats(h))
        html = convert_table_to_html(convert_stats_to_table(stats_list))
        stuff['html'] = html

    ## renormalize for bin widths
    bins = kwargs.pop('bins', None)
    if bins and isinstance(bins, list):
        for h in all_hists:
            renormalize_for_bin_widths(h, bins)

    ## stack background histograms
    if h_bkgs:
        assert len(h_bkgs) == len(n_bkgs), '%s\n%s' % (h_bkgs, n_bkgs)

        h_bkgs.reverse()
        n_bkgs.reverse()

        hstack = HistStack()
        for h in h_bkgs:
            hstack.Add(h)
        hstack.title = 'stack sum'
        hstack.drawstyle = 'HIST'
        stuff['stack'] = hstack

        h_bkgs.reverse()
        n_bkgs.reverse()

#    ## convert data to TGraphAsymmErrors
#    g_data = None
#    if h_data:
#        if __use_poissonize:
#            g_data = poissonize.GetPoissonizedGraph(h_data)
#        else:
#            g_data = ROOT.TGraphAsymmErrors()
#            i_g = 0
#            nbins = h_data.GetNbinsX()
#            for i_bin in xrange(1, nbins+1): # skip underflow/overflow
#                c = h_data.GetBinContent(i_bin)
#                e = h_data.GetBinError(i_bin)
#                if c != 0.0:
#                    g_data.SetPoint(i_g, h_data.GetBinCenter(i_bin), c)
#                    g_ratio.SetPointError(i_g,
#                            h_data.GetBinWidth(i_bin)/2.,
#                            h_data.GetBinWidth(i_bin)/2.,
#                            e,
#                            e)
#                i_g += 1

## build list of objects to draw
    objects = list()
    if h_bkgs:
        objects.append(stuff['stack'])
        objects.append(stuff['h_bkg_total'])
    if h_sigs:
        objects.extend(h_sigs)
    if h_data:
        objects.append(h_data)

    ## set xlimits and ylimits
    ypadding = 0.21
    logy_crop_value = 7e-3
    xmin, xmax, ymin, ymax = 0.0, 1.0, 0.0, 1.0
    if objects:
        xmin, xmax, ymin, ymax = get_limits(objects,
                                            logx=logx,
                                            logy=logy,
                                            ypadding=ypadding,
                                            logy_crop_value=logy_crop_value)
    if logy:
        ymin = 7e-3
    else:
        ymin = 0.0
    xlimits = (xmin, xmax)
    ylimits = (ymin, ymax)
    stuff['xlimits'] = xlimits
    stuff['ylimits'] = ylimits

    ## remove xtitle for do_ratio
    _xtitle = xtitle
    if h_data and h_bkg_total and kwargs.get('do_ratio'):
        _xtitle = ''

    ## make canvas
    canvas = Canvas(800, 600)
    stuff['canvas'] = canvas

    ## draw the objects
    if objects:
        canvas.cd()
        draw(objects,
             pad=canvas,
             xtitle=_xtitle,
             ytitle=ytitle,
             xlimits=xlimits,
             ylimits=ylimits)

    ## set log x/y, for some reason doesn't work before draw
    if logx or logy:
        if logx:
            canvas.SetLogx()
        if logy:
            canvas.SetLogy()
        canvas.Update()

    ## draw blind_line
    if has_blinded_data:
        if isinstance(blind, tuple):
            blind_list = list(blind)
        else:
            blind_list = [blind]
        blind_lines = list()
        for bl in blind_list:
            line_y1 = ymin
            line_y2 = ymax
            blind_line = ROOT.TLine(bl, line_y1, bl, line_y2)
            blind_line.SetLineColor(ROOT.kGray + 2)
            blind_line.SetLineStyle(7)
            blind_line.SetLineWidth(2)
            blind_line.Draw()
            blind_lines.append(blind_line)
        stuff['blind_lines'] = blind_lines
        canvas.Update()

    ## legend
    lefty = True
    if h_bkg_total:
        lefty = is_left_sided(h_bkg_total)
    elif h_data:
        lefty = is_left_sided(h_data)
    elif h_sigs:
        lefty = is_left_sided(h_sigs[0])

    if main_hists:
        header = '%.1f fb^{-1}, 13 TeV' % (lumi / 1000.0)
        if lefty:
            legend = Legend(main_hists,
                            pad=canvas,
                            header=header,
                            textsize=16,
                            topmargin=0.03,
                            leftmargin=0.60,
                            rightmargin=0.02,
                            entrysep=0.01,
                            entryheight=0.04)
        else:
            legend = Legend(main_hists,
                            pad=canvas,
                            header=header,
                            textsize=16,
                            topmargin=0.03,
                            leftmargin=0.03,
                            rightmargin=0.59,
                            entrysep=0.01,
                            entryheight=0.04)
        legend.Draw()
        stuff['legend'] = legend

    if h_sigs:
        #        header = 'ATLAS Internal'
        header = ''
        if lefty:
            legend2 = Legend(h_sigs,
                             pad=canvas,
                             header=header,
                             textsize=16,
                             topmargin=0.03,
                             leftmargin=0.37,
                             rightmargin=0.23,
                             entrysep=0.01,
                             entryheight=0.04)
        else:
            legend2 = Legend(h_sigs,
                             pad=canvas,
                             header=header,
                             textsize=16,
                             topmargin=0.03,
                             leftmargin=0.20,
                             rightmargin=0.40,
                             entrysep=0.01,
                             entryheight=0.04)
        legend2.Draw()
        stuff['legend2'] = legend2

    ## do_ratio
    if h_data and h_bkg_total and kwargs.get('do_ratio'):

        ## top canvas
        top_canvas = stuff.pop('canvas')
        stuff['top_canvas'] = top_canvas

        ## make SM/SM with error band: h_ratio_band
        i_sfratio = int(kwargs.get('sfratio', -1))
        if i_sfratio < 0:  # ratio plot of Data/Model
            h_ratio_band = h_bkg_total.Clone()
            nbins = h_ratio_band.GetNbinsX()
            for i_bin in xrange(nbins + 2):
                h_ratio_band.SetBinContent(i_bin, 1.0)
                c = h_bkg_total.GetBinContent(i_bin)
                e = h_bkg_total.GetBinError(i_bin) / c if c > 0.0 else 0.0
                h_ratio_band.SetBinError(i_bin, e)
            stuff['h_ratio_band'] = h_ratio_band
        else:  # ratio plot of Scale Factor for ith background
            hi = h_bkgs[i_sfratio]
            h_ratio_band = hi.Clone()
            nbins = h_ratio_band.GetNbinsX()
            for i_bin in xrange(nbins + 2):
                h_ratio_band.SetBinContent(i_bin, 1.0)
                c = hi.GetBinContent(i_bin)
                e = hi.GetBinError(i_bin) / c if c > 0.0 else 0.0
                h_ratio_band.SetBinError(i_bin, e)
            stuff['h_ratio_band'] = h_ratio_band

        ## make data/(SM) h_ratio
        if i_sfratio < 0:
            h_ratio = h_data.Clone()
            h_ratio.Divide(h_data, h_bkg_total, 1.0, 1.0)
            stuff['h_ratio'] = h_ratio
        else:
            ## SF1 = 1.0 + (data - MCtot) / MC1
            sfname = kwargs.get('sfname')
            sffile = kwargs.get('sffile')
            if not sfname:
                sfname = 'h_sf'
            hi = h_bkgs[i_sfratio]
            h_numer = h_data.Clone()
            h_numer.Add(h_bkg_total, -1.0)
            ## do the division
            h_ratio = h_data.Clone(sfname)
            h_ratio.Divide(h_numer, hi, 1.0, 1.0)
            ## add the 1.0
            nbins = h_ratio.GetNbinsX()
            for i_bin in xrange(nbins + 2):
                c = h_ratio.GetBinContent(i_bin)
                h_ratio.SetBinContent(i_bin, c + 1.0)
                h_ratio_band.SetBinContent(i_bin, c + 1.0)
            ## ignore bins with no data for SF
            for i_bin in xrange(nbins + 2):
                c = h_data.GetBinContent(i_bin)
                if c <= 0:
                    h_ratio.SetBinContent(i_bin, 0.0)
                    h_ratio.SetBinError(i_bin, 0.0)
                    h_ratio_band.SetBinError(i_bin, 0.0)
            stuff['h_ratio'] = h_ratio
            if sffile:
                f_out = ipyhep.file.write(h_ratio, sffile)
#                f_out.Close()

## convert ratio to a TGraphErrors so that Draw('E0')
## shows error bars for points off the pad
        g_ratio = ROOT.TGraphErrors()
        i_g = 0
        for i_bin in xrange(1, nbins + 1):  # skip underflow/overflow
            ratio_content = h_ratio.GetBinContent(i_bin)
            if ratio_content != 0.0:
                g_ratio.SetPoint(i_g, h_ratio.GetBinCenter(i_bin),
                                 ratio_content)
                g_ratio.SetPointError(i_g,
                                      h_ratio.GetBinWidth(i_bin) / 2.,
                                      h_ratio.GetBinError(i_bin))
                i_g += 1
            else:
                h_ratio.SetBinError(i_bin, 0.0)
        stuff['g_ratio'] = g_ratio

        ## style ratio
        h_ratio_band.title = 'bkg uncert.'
        if i_sfratio < 0:
            h_ratio_band.linecolor = ipyhep.style.yellow
        else:
            h_ratio_band.linecolor = ipyhep.style.light_gray
        h_ratio_band.linewidth = 0
        h_ratio_band.markerstyle = 0
        if i_sfratio < 0:
            h_ratio_band.fillcolor = ipyhep.style.yellow
        else:
            h_ratio_band.linecolor = ipyhep.style.light_gray
        h_ratio_band.fillstyle = ipyhep.style.fill_solid
        h_ratio_band.drawstyle = 'E2'
        h_ratio_band.legendstyle = 'F'
        h_ratio.title = 'ratio'
        h_ratio.linecolor = ipyhep.style.black
        h_ratio.linewidth = 2
        h_ratio.markercolor = ipyhep.style.black
        h_ratio.markerstyle = 20
        h_ratio.markersize = 1.2
        h_ratio.fillstyle = ipyhep.style.fill_hollow
        h_ratio.drawstyle = 'PE'
        h_ratio.legendstyle = 'LP'

        ## bottom canvas
        bottom_canvas = Canvas(800, 600)
        bottom_canvas.cd()
        stuff['bottom_canvas'] = bottom_canvas

        ## set ratio ylimits
        ratio_min = kwargs.get('ratio_min', -0.2)
        ratio_max = kwargs.get('ratio_max', 2.2)
        ratio_ylimits = (ratio_min, ratio_max)

        ## draw ratio band
        if i_sfratio < 0:
            _ytitle = 'Data / Model'
        else:
            hi = h_bkgs[i_sfratio]
            _ytitle = 'SF(%s)' % hi.title
        draw([h_ratio_band],
             pad=bottom_canvas,
             xtitle=xtitle,
             ytitle=_ytitle,
             xlimits=xlimits,
             ylimits=ratio_ylimits)

        ## set log x/y, for some reason doesn't work before draw?
        if logx:
            bottom_canvas.SetLogx()
            bottom_canvas.Update()

        ### make horiz lines in ratio plot every 0.5:
        line_ys = [
            y / 10.0
            for y in range(10 *
                           int(round(ratio_min)), 10 * int(round(ratio_max)) +
                           5, 5)
        ]
        line_x1 = canvas.GetUxmin()
        line_x2 = canvas.GetUxmax()
        line_xwidth = abs(line_x2 - line_x1)
        lines = []
        for line_y in line_ys:
            line = ROOT.TLine(line_x1 + 0.02 * line_xwidth, line_y,
                              line_x2 - 0.02 * line_xwidth, line_y)
            line.SetLineWidth(1)
            line.SetLineStyle(7)
            if line_y == 1.0:
                line.SetLineColor(ROOT.kGray + 2)
            else:
                line.SetLineColor(ROOT.kGray + 0)
            line.Draw()
            lines.append(line)
        stuff['lines'] = lines

        ## draw blind_line
        if has_blinded_data:
            if isinstance(blind, tuple):
                blind_list = list(blind)
            else:
                blind_list = [blind]
            blind_lines = list()
            for bl in blind_list:
                line_y1 = ymin
                line_y2 = ymax
                blind_line = ROOT.TLine(bl, line_y1, bl, line_y2)
                blind_line.SetLineColor(ROOT.kGray + 2)
                blind_line.SetLineStyle(7)
                blind_line.SetLineWidth(2)
                blind_line.Draw()
                blind_lines.append(blind_line)
            stuff['blind_lines2'] = blind_lines
            canvas.Update()

        ## draw ratio
        g_ratio.Draw('PE0')
        #        h_ratio.GetYaxis().SetRangeUser(ratio_min, ratio_max)
        #        h_ratio.Draw('PE,SAME')

        ## shared canvas
        shared_canvas = Canvas(800, 800)
        shared_plot = plot_shared_axis(top_canvas,
                                       bottom_canvas,
                                       canvas=shared_canvas,
                                       split=0.35,
                                       axissep=0.01)
        stuff['canvas'] = shared_canvas
        canvas = shared_canvas

    ## save figures
    save = kwargs.get('save')

    if save is None:  # NOTE: save can be False to skip saving
        save = ['pdf', 'png']

    if save:
        ipyhep.file.save_figures(canvas, x, save)

    global results
    results = stuff
    return stuff