def main(args):
    """Main"""
    mcdata = get_dataframe(args.mcfile, columns=MC_VARIABLES)
    chi1data = get_dataframe(args.chic1file, 'tr', columns=TOY_VARIABLES)
    chi2data = get_dataframe(args.chic2file, 'tr', columns=TOY_VARIABLES)

    mc_ratios = OrderedDict()
    toy_ratios = OrderedDict()

    for name in SELECTIONS_TOY:
        toy_ratios[name] = OrderedDict()
        mc_ratios[name] = OrderedDict()

        toy_sel = SELECTIONS_TOY[name]
        mc_sel = SELECTIONS_MC[name]

        for var in VARIABLES:
            hist_sett = VARIABLES[var]['sett']
            toy_ratios[name][var] = get_ratio(chi1data, chi2data,
                                              VARIABLES[var]['var'], toy_sel,
                                              hist_sett, get_weight_func())
            mc_ratios[name][var] = get_ratio_mc(mcdata, VARIABLES[var]['var'],
                                                mc_sel, hist_sett)

    set_TDR_style()
    for name in SELECTIONS_TOY:
        for var in VARIABLES:
            leg = setup_legend(*LEGPOS[var])
            can = mkplot(mc_ratios[name][var],
                         attr=[PLOT_ATTRIBUTES[name]['mc']],
                         drawOpt='E2',
                         legOpt='F',
                         xLabel=LABELS[var],
                         yLabel='#chi_{c2} / #chi_{c1}',
                         leg=leg,
                         legEntries=['real mc'])
            can = mkplot(toy_ratios[name][var],
                         attr=[PLOT_ATTRIBUTES[name]['toy']],
                         drawOpt='E1same',
                         legOpt='PLE',
                         can=can,
                         xLabel=LABELS[var],
                         yLabel='#chi_{c2} / #chi_{c1}',
                         leg=leg,
                         legEntries=['toy mc'])
            latex = setup_latex()
            can.add_tobject(latex)
            put_on_latex(latex, [(0.18, 0.96, name)])
            savename = '_'.join(['comp_real_toy', name,
                                 var]).replace(' + ', '_')
            can.SaveAs(savename + '.pdf')
def make_var_plot(nom_file, var_files, var):
    """
    Make a variation plot comparing the nominal PPD to the variations PPDs
    """
    nom_ppd = get_scaled_ppd(nom_file, var)
    nom_quants = get_quantiles(nom_ppd, QUANTILES)
    nom_lo, nom_hi = np.diff(nom_quants)
    nom_graph = get_nom_graph(len(var_files), nom_lo, nom_hi)

    # var_graphs = get_var_graphs_wrt_nominal(var_files, nom_quants, var)
    var_graphs = get_var_graphs_wrt_nominal(
        var_files, [nom_ppd.GetMean(), nom_ppd.GetRMS()], var)

    xran = np.max([nom_lo, nom_hi]) * 1.75
    yran = [-0.25, len(var_files) - 0.75]

    can = mkplot(nom_graph,
                 attr=[{
                     'fillalpha': (default_colors()[1], 0.5)
                 }],
                 drawOpt='E2',
                 xLabel=get_label(var),
                 xRange=[-xran, xran],
                 yRange=yran)
    mkplot(r.TLine(0, yran[0], 0, yran[1]),
           can=can,
           drawOpt='same',
           attr=default_attributes(widht=2)[1:])
    mkplot(var_graphs, drawOpt='samePE', can=can, attr=VAR_ATTR)

    phist = can.pltables[0]
    phist.GetYaxis().SetLabelSize(0)
    phist.GetYaxis().SetTickSize(0)

    ltx = setup_latex()
    put_on_latex(ltx, get_labels(var_files.keys()), ndc=True)
    ltx.Draw()
    can.Draw()

    return can
Esempio n. 3
0
    def plot(self, wsp, verbose=False, publication=False):
        """
        Plot the fit results from the passed workspace

        Args:
            wsp (ROOT.RooWorkspace): The workspace that holds the model and the
                data as well as the fit results
            verbose (boolean): Print some more information about the fit status
                onto the plots (mainly for debugging)
            publication (boolean, optional): Make the plots in publication
                quality (negates the verbose argument automatically)
        """
        data = wsp.data('full_data')

        cans = OrderedDict()
        g_chi2, g_ndf = 0, 0

        fvar = get_var(wsp, self.fit_var)
        n_bins = int(round(((fvar.getMax() - fvar.getMin()) / BIN_WIDTH)))

        wsp.loadSnapshot('snap_two_dim')

        for bin_name, bin_borders in self.bins.iteritems():
            frame, leg = self._plot_bin(wsp, data, bin_name, bin_borders,
                                        n_bins, publication)
            b_chi2, b_ndf = get_chi2_ndf(frame, 'full_pdf_curve', 'data_hist')
            logging.debug('bin: {}: chi2 / number bins = {:.2f} / {}'.format(
                bin_name, b_chi2, b_ndf))
            g_chi2 += b_chi2
            g_ndf += b_ndf

            can = _setup_canvas(None)  # returns a TCanvasWrapper
            can.cd()

            pad = r.TPad('result_pad', 'result pad', 0, 0.3, 1, 0.98)
            r.SetOwnership(pad, False)

            if publication:
                pad.SetBottomMargin(0)

            pad.Draw()
            pad.cd()
            frame.Draw()
            can.add_tobject(pad)
            leg.Draw()
            can.add_tobject(leg)

            # pulls
            pull_frame = self._pull_plot(wsp, frame, publication)

            can.cd()
            pull_pad = r.TPad('pull_pad', 'pull pad', 0, 0, 1, 0.3)
            r.SetOwnership(pull_pad, False)
            if publication:
                pull_pad.SetTopMargin(0)
                pull_pad.SetBottomMargin(0.275)
            else:
                pull_pad.SetBottomMargin(0.2)
            pull_pad.Draw()
            pull_pad.SetGridy()
            pull_pad.cd()
            pull_frame.Draw()
            can.add_tobject(pull_pad)

            cans[bin_name] = can

        fit_res = wsp.genobj('fit_res_two_dim')
        n_float_pars = fit_res.floatParsFinal().getSize()
        g_ndf -= n_float_pars
        logging.debug('Floating parameters in fit: {}'.format(n_float_pars))
        logging.info('Global chi2 / ndf = {:.2f} / {}'.format(g_chi2, g_ndf))

        add_info = []

        # loop again over all canvases and put the global chi2 / ndf there
        add_info.append(
            (0.15, 0.875,
             '(global) #chi^{{2}} / ndf = {:.1f} / {}'.format(g_chi2, g_ndf)))

        if verbose and not publication:
            status = get_var(wsp, '__fit_status__').getVal()
            cov_qual = get_var(wsp, '__cov_qual__').getVal()
            add_info.append(
                (0.15, 0.825,
                 'status = {}, covQual = {}'.format(int(status),
                                                    int(cov_qual))))
            # Check if the simultaneous negative log-likelihood is present in
            # the workspace or create it if it is not yet present.
            # Since the snapshot values of the fit result are already loaded it
            # can be directly evaluated to get the value at the minimum
            sim_nll = get_var(wsp, 'sim_nll')
            if sim_nll is None:
                sim_nll = self._create_nll(
                    wsp, (rf.Extended(True), rf.Offset(True)))
            min_nll = sim_nll.getVal()

            aic = calc_info_crit(fit_res, min_nll)
            bic = calc_info_crit(fit_res, min_nll, data.numEntries())
            add_info.append(
                (0.15, 0.775, 'AIC = {:.1f}, BIC = {:.1f}'.format(aic, bic)))

        latex = setup_latex()
        if publication:
            latex.SetTextSize(0.04)
            add_info[0] = (0.185, 0.89, add_info[0][2])

        for bin_name, can in cans.iteritems():
            res_pad = can.attached_tobjects[0]
            res_pad.cd()
            put_on_latex(latex, add_info, ndc=True)
            bin_info = get_bin_info_text(bin_name, self.bins)
            put_on_latex(latex, bin_info, ndc=True)

        # for easier debugging at the moment
        return cans
Esempio n. 4
0
def make_plot_with_syst(graphs,
                        variable,
                        syst_file,
                        add_fit=False,
                        vs_pt_m=False):
    """
    Make a plot including the systematic uncertainties.
    First combine the stat. and syst. errors by summing them in quadrature then
    plot the combined as well as the stat. only graphs onto the plot.
    Only uses the +/- 1 sigma stat. uncertainties
    """
    syst_graph = syst_file.Get('{}_v_pt_syst'.format(variable))
    stat_graph = graphs['1']
    comb_graph = get_combined_graph(stat_graph, syst_graph)

    xran = [8, 30]
    xlab = PTLABEL

    if vs_pt_m:
        xran = [v / m_psiPDG for v in xran]
        comb_graph = scale_graph_x(comb_graph, 1 / m_psiPDG)
        stat_graph = scale_graph_x(stat_graph, 1 / m_psiPDG)
        xlab = PTMLABEL

    leg = setup_legend(0.675, 0.74, 0.88, 0.88)
    can = mkplot(comb_graph,
                 drawOpt='PE2',
                 attr=ATTR['combined'],
                 xRange=xran,
                 xLabel=xlab,
                 yRange=YRANGES[variable],
                 yLabel=YLABELS[variable],
                 leg=leg,
                 legEntries=['stat. + syst.'],
                 legOpt='PF')

    # remove the x uncertainties to avoid having the vertical line in the plot
    # stat_graph = remove_x_errors(stat_graph)
    mkplot(stat_graph,
           can=can,
           drawOpt='PE2same',
           attr=ATTR['stat only'],
           leg=leg,
           legEntries=['stat. only'],
           legOpt='F')

    # stat only covers the point of the combined one. Plot them again
    mkplot(comb_graph, drawOpt='PEX0same', attr=ATTR['combined'], can=can)

    add_auxiliary_info(can, 2012, prelim=True, pos='left')

    if add_fit:
        lin_func = r.TF1('lin_func', '[0] + [1] * x[0]', *xran)
        fit_res = comb_graph.Fit(lin_func, 'SEX00')
        chi2, ndf = fit_res.Chi2(), fit_res.Ndf()
        p0, p1 = [lin_func.GetParameter(i) for i in [0, 1]]

        const_func = r.TF1('const_func', '[0]', *xran)
        fit_res = comb_graph.Fit(const_func, 'SEX00')
        chi2_c, ndf_c = fit_res.Chi2(), fit_res.Ndf()
        p0c, p0ce = [const_func.GetParameter(0), const_func.GetParError(0)]

        mkplot(lin_func, drawOpt='Lsame', can=can, attr=ATTR['fit'])

        ltx = setup_latex()
        put_on_latex(ltx, [
            (0.5, 0.35, 'linear fit: {:.3f} + {:.3f} x p_{{T}}'.format(p0,
                                                                       p1)),
            (0.5, 0.3, '#chi^{{2}} / ndf = {:.2f} / {}'.format(chi2, ndf)),
            (0.5, 0.25, 'const. fit: {:.3f} #pm {:.3f}'.format(p0c, p0ce)),
            (0.5, 0.2, '#chi^{{2}} / ndf = {:.2f} / {}'.format(chi2_c, ndf_c))
        ],
                     ndc=True)
        ltx.Draw()
        can.Update()

    return can
Esempio n. 5
0
def main(args):
    """Main"""
    set_TDR_style()
    fitfile = r.TFile.Open(args.fitfile)

    cont_1sigma = get_contour(fitfile.Get('chi2_scan_contour_1sigma'))
    cont_2sigma = get_contour(fitfile.Get('chi2_scan_contour_2sigma'))
    cont_3sigma = get_contour(fitfile.Get('chi2_scan_contour_3sigma'))

    leg = setup_legend(0.5, 0.78, 0.8, 0.94)
    leg.SetTextSize(0.035)
    leg.SetEntrySeparation(0.005)
    leg.SetFillStyle(1001)

    can = mkplot([cont_1sigma, cont_2sigma, cont_3sigma],
                 drawOpt='L',
                 xRange=[-1, 1.6],
                 xLabel='#lambda_{#vartheta}^{#chi_{c1}}',
                 yRange=[-1.2, 1.6],
                 yLabel='#lambda_{#vartheta}^{#chi_{c2}}',
                 attr=CONT_ATTR,
                 leg=leg,
                 legEntries=['{} % CL'.format(v) for v in [68, 95, 99]],
                 legOpt='L')

    mkplot(get_phys_region(),
           can=can,
           drawOpt='same',
           attr=[{
               'color': r.kRed,
               'line': 7,
               'width': 3
           }])

    mkplot([r.TLine(0, -1.2, 0, 1.6),
            r.TLine(-1, 0, 1.6, 0)],
           can=can,
           drawOpt='same',
           attr=[{
               'color': 12,
               'line': 7,
               'width': 2
           }])

    mkplot(r.TGraph(1, np.array([0]), np.array([0])),
           can=can,
           drawOpt='Psame',
           attr=[{
               'color': 1,
               'marker': 24,
               'size': 2.75
           }])

    mkplot(get_jz_graph(),
           can=can,
           drawOpt='Psame',
           attr=[{
               'color': 1,
               'marker': 30,
               'size': 3
           }])

    ltx = setup_latex()
    ltx.SetTextSize(0.04)
    put_on_latex(ltx, [(-0.4, 1.3, 'J_{z}'), (-0.4, 1.1, '#pm1'),
                       (0.975, 1.1, '0'), (-0.54, 0.95, '#pm2'),
                       (-0.54, -0.38, '#pm1'), (-0.47, -0.65, '0')],
                 ndc=False)

    add_auxiliary_info(can, 2012, 'left')
    can.SaveAs(args.outfile)
def make_comp_plot(graph, intgraph, fit=False):
    """
    Make one comparison plot and return the TCanvasWrapper
    """
    plt_attr = [{
        'color': default_colors()[0],
        'marker': 20,
        'size': 1.5
    }, {
        'color': default_colors()[1],
        'marker': 24,
        'size': 0.5,
        'fillalpha': (default_colors()[1], 0.5)
    }, {
        'color': default_colors()[4],
        'line': 2,
        'width': 2
    }]

    graph_name = graph.GetName().replace('_v_costh', '')
    if graph_name in FIX_RANGES:
        yRange = FIX_RANGES[graph_name]
    else:
        yRange = None

    ylabel = YLABELS[graph_name] if graph_name in YLABELS else graph_name

    can = mkplot(graph,
                 xRange=[0, 1],
                 drawOpt='PE',
                 attr=plt_attr[0:],
                 yRange=yRange,
                 yLabel=ylabel,
                 xLabel='|cos#vartheta^{HX}|')

    # some cosmetics
    can.SetTopMargin(0.05)
    can.SetRightMargin(0.02)
    can.SetLeftMargin(0.15)
    can.pltables[0].SetTitleOffset(2.1, 'Y')

    if intgraph is not None or fit:
        leg = setup_legend(0.65, 0.85, 0.97, 0.94)

    if intgraph is not None:
        can = mkplot(intgraph,
                     can=can,
                     drawOpt='sameP2',
                     attr=plt_attr[1:],
                     leg=leg,
                     legEntries=['cos#vartheta^{HX} int. fit'],
                     legOpt='PLEF')
        can = mkplot(intgraph, can=can, drawOpt='samePE', attr=plt_attr[1:])
    if fit:
        const = r.TF1('const', '[0]', 0, 1)
        const.SetParameter(0, np.array(graph.GetX())[0])
        fit_res = graph.Fit(const, 'NSEX0')

        can = mkplot(const,
                     can=can,
                     drawOpt='sameL',
                     attr=plt_attr[2:],
                     leg=leg,
                     legEntries=['fit to constant'],
                     legOpt='L')

        ltx = setup_latex()
        can.add_tobject(ltx)
        put_on_latex(ltx,
                     [(0.595, 0.2, 'c = {:.2e} +/- {:.2e}'.format(
                         const.GetParameter(0), const.GetParError(0))),
                      (0.595, 0.25, '#chi^{{2}} / ndf = {:.2f} / {}'.format(
                          fit_res.Chi2(), fit_res.Ndf()))],
                     ndc=True)
    can.Update()

    return can
Esempio n. 7
0
    def plot(self, wsp, pdfname, snapname='', add_cut='', **kwargs):
        """
        Make a plot of the model and the fitted data and save as pdf.

        Args:
            wsp (ROOT.RooWorkspace): workspace where all the information
                (including data and model) is stored
            pdfname (str): Name of the created pdf under which the plot will be
                stored.
            snapname (str, optional): Name of snapshot that will be loaded
                before plotting
            add_cut (str, optional): Additional cut to apply to the dataset
                before plotting. NOTE: all used variables have to be present in
                the dataset

        Keyword Args:
            logy (bool): Set log on y scale of distribution plot
            weighted_fit (bool): Assume that the fit has done using weights and
                calculate the data uncertainties using these weights.
            verbose (bool): Put information on the fit status and the covariance
                matrix quality onto the fit
        """
        fitresname = None
        if snapname:
            wsp.loadSnapshot(snapname)
            fitresname = snapname.replace('snap', 'fit_res')

        # Starting from ROOT v6.12 it is possible to set this on individual axis
        r.TGaxis.SetMaxDigits(3)

        mvar = get_var(wsp, self.mname)
        plot_data = wsp.data('full_data')
        if add_cut:
            plot_data = plot_data.reduce(add_cut)

        nbins = int((mvar.getMax() - mvar.getMin()) / BIN_WIDTH)

        # TODO: find a better heuristic to do this here
        nevents_data = plot_data.numEntries()
        logging.debug(
            'Number of events in reduced sample: {}'.format(nevents_data))
        while nevents_data / nbins < 50:
            nbins /= 2

        frame = mvar.frame(rf.Bins(nbins))

        frame.SetTitle("")
        frame.GetYaxis().SetTitleOffset(1.3)
        frame.GetYaxis().SetTitle('Events / {:.1f} MeV'.format(
            (mvar.getMax() - mvar.getMin()) / nbins * 1000))

        full_pdf = wsp.pdf(self.full_model)

        leg = self._setup_legend()

        if kwargs.pop('weighted_fit', True):
            plot_data.plotOn(frame, rf.MarkerSize(0.8), rf.Name('data_hist'),
                             rf.DataError(r.RooAbsData.SumW2))
        else:
            plot_data.plotOn(frame, rf.MarkerSize(0.8), rf.Name('data_hist'))

        full_pdf.plotOn(
            frame,
            rf.LineWidth(2),
            # rf.ProjWData(plot_data),
            rf.Name('full_pdf_curve'))

        leg.AddEntry(frame.getCurve('full_pdf_curve'), 'sum', 'l')

        for name, lst, lcol, legentry in self.components:
            full_pdf.plotOn(frame, rf.Components(name), rf.LineStyle(lst),
                            rf.LineColor(lcol), rf.LineWidth(2), rf.Name(name))
            leg.AddEntry(frame.getCurve(name), legentry, 'l')

        info_text = []
        if fitresname is not None:
            fit_res = wsp.genobj(fitresname)
            chi2, ndf = get_chi2_ndf(frame, 'full_pdf_curve', 'data_hist',
                                     fit_res)
            info_text.append(
                (0.15, 0.875, '#chi^{{2}}/ndf = {:.1f} / {}'.format(chi2,
                                                                    ndf)))

        if kwargs.pop('verbose', False):
            status = get_var(wsp, '__fit_status__').getVal()
            cov_qual = get_var(wsp, '__cov_qual__').getVal()
            info_text.append(
                (0.15, 0.825,
                 'status = {}, covQual = {}'.format(int(status),
                                                    int(cov_qual))))
            if fitresname is not None:
                aic = calc_info_crit(fit_res)
                bic = calc_info_crit(fit_res, nevents_data)
                info_text.append(
                    (0.15, 0.775,
                     'AIC = {:.1f}, BIC = {:.1f}'.format(aic, bic)))

        pull_frame = mvar.frame(rf.Bins(nbins))
        hpull = frame.pullHist('data_hist', 'full_pdf_curve', True)
        hpull.SetMarkerSize(0.8)
        pull_frame.addPlotable(hpull, 'P')

        pull_frame.SetTitle("")
        pull_frame.GetYaxis().SetTitle("pull")
        pull_frame.GetXaxis().SetTitleSize(0.08)
        pull_frame.GetYaxis().SetTitleSize(0.08)
        pull_frame.GetXaxis().SetLabelSize(0.08)
        pull_frame.GetYaxis().SetLabelSize(0.08)
        pull_frame.GetYaxis().SetTitleOffset(0.4)
        pull_frame.GetYaxis().SetRangeUser(-5.99, 5.99)

        latex = setup_latex()
        can = r.TCanvas(create_random_str(16), '', 50, 50, 600, 600)
        can.cd()

        pad = r.TPad('mass_pad', 'mass_pad', 0, 0.3, 1, 1)
        r.SetOwnership(pad, False)
        pad.Draw()
        pad.cd()
        if kwargs.pop('logy', False):
            pad.SetLogy()
            pdfname = pdfname.replace('mass_fit', 'mass_fit_log')
        frame.Draw()
        leg.Draw()
        put_on_latex(latex, info_text, ndc=True)

        can.cd()
        pull_pad = r.TPad('pull_pad', 'pull_pad', 0, 0, 1, 0.3)
        r.SetOwnership(pull_pad, False)
        pull_pad.Draw()
        pull_pad.SetGridy()
        pull_pad.SetBottomMargin(0.2)
        pull_pad.cd()
        pull_frame.Draw()

        can.SaveAs(pdfname)