示例#1
0
    def test_tgraph_asymm_errors_correlation(self):
        """
        Check that the uncertainties are calculated correctly with a correlation
        coefficient different from 0
        """
        n_graph = get_random_graph(r.TGraphAsymmErrors, 5)
        d_graph = get_random_graph(r.TGraphAsymmErrors, 5)
        rho = np.random.uniform(-1, 1, 1)
        r_graph = gu.divide_graphs(n_graph, d_graph, rho)

        # Just to be sure that there is no influence on the ratio check it
        # All checks concerning x-direction are not done here!
        y_vals = np.array(r_graph.GetY())
        yn_vals = np.array(n_graph.GetY())
        yd_vals = np.array(d_graph.GetY())
        npt.assert_allclose(y_vals, yn_vals / yd_vals)

        _, _, yle, yhe = gu.get_errors(r_graph)
        _, _, ydle, ydhe = gu.get_errors(d_graph)
        _, _, ynle, ynhe = gu.get_errors(n_graph)

        anl_errs = self._get_analytic_err(yn_vals, yd_vals, ynle, ydle, rho)
        npt.assert_allclose(yle, anl_errs)
        anh_errs = self._get_analytic_err(yn_vals, yd_vals, ynhe, ydhe, rho)
        npt.assert_allclose(yhe, anh_errs)
示例#2
0
    def test_tgraph_asymm_errors(self):
        """Test that TGraphAsymmErrors are handled correctly"""
        n_vals = 25
        x_vals = np.random.uniform(0, 10, n_vals)
        y_vals = np.random.uniform(0, 10, n_vals)
        xl_errs = np.random.uniform(0, 1, n_vals)
        yl_errs = np.random.uniform(0, 1, n_vals)
        xh_errs = np.random.uniform(0, 1, n_vals)
        yh_errs = np.random.uniform(0, 1, n_vals)

        in_graph = r.TGraphAsymmErrors(n_vals, x_vals, y_vals, xl_errs,
                                       xh_errs, yl_errs, yh_errs)

        r_low, r_high = 3, 8
        in_range_idcs = (x_vals > r_low) & (x_vals < r_high)
        r_graph = gu.graph_in_range(in_graph, r_low, r_high)

        self.assertTrue(isinstance(r_graph, r.TGraphAsymmErrors))

        npt.assert_allclose(np.array(r_graph.GetX()), x_vals[in_range_idcs])
        npt.assert_allclose(np.array(r_graph.GetY()), y_vals[in_range_idcs])

        rlx_errs, rhx_errs, rly_errs, rhy_errs = gu.get_errors(r_graph)
        npt.assert_allclose(rlx_errs, xl_errs[in_range_idcs])
        npt.assert_allclose(rly_errs, yl_errs[in_range_idcs])
        npt.assert_allclose(rhx_errs, xh_errs[in_range_idcs])
        npt.assert_allclose(rhy_errs, yh_errs[in_range_idcs])
示例#3
0
def remove_y_errors(graph):
    """
    Get a (copy) of the passed graph with removed y errors
    """
    x_vals, y_vals = np.array(graph.GetX()), np.array(graph.GetY())
    x_lo, x_hi, _, _ = get_errors(graph)

    return r.TGraphAsymmErrors(len(x_vals), x_vals, y_vals, x_lo, x_hi)
示例#4
0
def remove_x_errors(graph):
    """
    Get a (copy) of the passed graph with removed x errors
    """
    x_vals, y_vals = np.array(graph.GetX()), np.array(graph.GetY())
    _, _, y_lo, y_hi = get_errors(graph)

    nbins = len(x_vals)
    x_err = np.zeros(nbins, dtype=float)

    return r.TGraphAsymmErrors(nbins, x_vals, y_vals, x_err, x_err, y_lo, y_hi)
示例#5
0
    def test_tgraph_errors(self):
        graph = get_random_graph(r.TGraphErrors)
        xerr, yerr = gu.get_errors(graph)

        root_x_err, root_y_err = [], []
        for i in xrange(graph.GetN()):
            root_x_err.append(graph.GetErrorX(i))
            root_y_err.append(graph.GetErrorY(i))

        npt.assert_allclose(np.array(root_x_err), xerr)
        npt.assert_allclose(np.array(root_y_err), yerr)
示例#6
0
    def test_tgraph_errors(self):
        """Check that the TGraphErrors are handled correctly"""
        n_graph = get_random_graph(r.TGraphErrors, 5)
        d_graph = get_random_graph(r.TGraphErrors, 5)
        r_graph = gu.divide_graphs(n_graph, d_graph)

        npt.assert_allclose(
            np.array(r_graph.GetY()),
            np.array(n_graph.GetY()) / np.array(d_graph.GetY()))

        npt.assert_allclose(np.array(r_graph.GetX()), np.array(n_graph.GetX()))

        x_errs, y_errs = gu.get_errors(r_graph)
        xn_errs, yn_errs = gu.get_errors(n_graph)
        npt.assert_allclose(x_errs, xn_errs)

        _, yd_errs = gu.get_errors(d_graph)

        an_errs = self._get_analytic_err(np.array(n_graph.GetY()),
                                         np.array(d_graph.GetY()), yn_errs,
                                         yd_errs)

        npt.assert_allclose(y_errs, an_errs)
示例#7
0
    def test_tgraph_asymm_errors(self):
        """Check that TGraphAsymmErrors are handled correctly"""
        n_graph = get_random_graph(r.TGraphAsymmErrors, 5)
        d_graph = get_random_graph(r.TGraphAsymmErrors, 5)
        r_graph = gu.divide_graphs(n_graph, d_graph)

        xn_vals, yn_vals = np.array(n_graph.GetX()), np.array(n_graph.GetY())
        yd_vals = np.array(d_graph.GetY())

        x_vals, y_vals = np.array(r_graph.GetX()), np.array(r_graph.GetY())
        npt.assert_allclose(y_vals, yn_vals / yd_vals)
        npt.assert_allclose(x_vals, xn_vals)

        xle, xhe, yle, yhe = gu.get_errors(r_graph)
        xnle, xnhe, ynle, ynhe = gu.get_errors(n_graph)
        _, _, ydle, ydhe = gu.get_errors(d_graph)
        npt.assert_allclose(xle, xnle)
        npt.assert_allclose(xhe, xnhe)

        anl_errs = self._get_analytic_err(yn_vals, yd_vals, ynle, ydle)
        npt.assert_allclose(yle, anl_errs)
        anh_errs = self._get_analytic_err(yn_vals, yd_vals, ynhe, ydhe)
        npt.assert_allclose(yhe, anh_errs)
示例#8
0
def get_combined_graph(stat, syst):
    """
    Get the combined graph of the statistical and systematical uncertainties
    (added in quadrature)
    """
    syst_uncer = np.array(syst.GetY())  # stored in y-values
    n_bins = len(syst_uncer)
    xlow, xhigh, ylow, yhigh = get_errors(stat)
    xcentral, ycentral = np.array(stat.GetX()), np.array(stat.GetY())

    ylow = np.sqrt(ylow**2 + syst_uncer**2)
    yhigh = np.sqrt(yhigh**2 + syst_uncer**2)

    return r.TGraphAsymmErrors(n_bins, xcentral, ycentral, xlow, xhigh, ylow,
                               yhigh)
示例#9
0
    def test_tgraph_asymm_errors(self):
        graph = get_random_graph(r.TGraphAsymmErrors)
        xlo, xhi, ylo, yhi = gu.get_errors(graph)

        rxlo, rxhi, rylo, ryhi = [], [], [], []
        for i in xrange(graph.GetN()):
            rxlo.append(graph.GetErrorXlow(i))
            rxhi.append(graph.GetErrorXhigh(i))
            rylo.append(graph.GetErrorYlow(i))
            ryhi.append(graph.GetErrorYhigh(i))

        npt.assert_allclose(np.array(rxlo), xlo)
        npt.assert_allclose(np.array(rxhi), xhi)
        npt.assert_allclose(np.array(rylo), ylo)
        npt.assert_allclose(np.array(ryhi), yhi)
示例#10
0
def calc_chi2(pred_hist, data_graph):
    """
    Calculate the chi2 between the predictor histogram and the data graph
    """
    # Need to select the bins without over- and underflow bin here
    pred = np.array([b for b in pred_hist][1:pred_hist.GetNbinsX() + 1])
    data_central = np.array(data_graph.GetY())
    _, _, data_err, _ = get_errors(data_graph)

    def chisquare((norm,)):
        return np.sum((( norm * pred - data_central) / data_err)**2)

    min_res = minimize(chisquare, np.array(data_central[0]), method='nelder-mead')
    fit_norm = min_res.x[0]

    return np.sum(((fit_norm * pred - data_central) / data_err)**2), fit_norm
    def setUp(self):
        self.func = r.TF1('test_func',
                          '[0] * (1 + [1] * x[0] + [2] * x[0]*x[0])', -2, 2)
        self.func.SetParameters(1, 2.0, -2.0)

        self.func_x_max = 2
        self.func_x_min = -2
        self.func_y_min = -11
        self.func_y_max = 1.5

        # Use TGraphAsymmErrors with random errors
        self.graph = r.TGraphAsymmErrors(10, np.linspace(0, 4, 10),
                                         np.sqrt(np.linspace(4, 16, 10)),
                                         np.random.uniform(size=10),
                                         np.random.uniform(size=10),
                                         np.random.uniform(size=10),
                                         np.random.uniform(size=10))
        gxlo, gxhi, gylo, gyhi = get_errors(self.graph)

        graph_x = np.array(self.graph.GetX())
        graph_y = np.array(self.graph.GetY())

        self.graph_x_max = np.max(graph_x + gxhi)
        self.graph_x_min = np.min(graph_x - gxlo)
        self.graph_y_max = np.max(graph_y + gyhi)
        self.graph_y_min = np.min(graph_y - gylo)

        self.hist = r.TH1D(create_random_str(8), '', 10, -3, 1)
        self.hist.Fill(-1)
        # Fill one event into each bin to have non-trivial results
        for i in xrange(12):
            self.hist.Fill(-3.2 + 4.0 / 10 * i)

        self.hist_x_max = 1
        self.hist_x_min = -3
        self.hist_y_max = 2
        self.hist_y_min = 1

        # For 2D histograms we don't need to fill the histogram since the min
        # and max values do not depend on it
        self.hist2d = r.TH2D(create_random_str(8), '', 10, -3, 1, 10, 4, 5)
        self.hist2d_x_max = 1
        self.hist2d_x_min = -3
        self.hist2d_y_max = 5
        self.hist2d_y_min = 4
示例#12
0
def get_largest_dev_graph(diff_graphs):
    """
    Get the graph containing in each point the largest deviation from 0 as
    uncertainties. The uncertainties of the input graphs are ignored for now.
    """
    y_vals = np.array([g.GetY() for g in diff_graphs])
    max_dev = np.max(y_vals, axis=0)
    min_dev = -np.min(y_vals, axis=0)

    # Clean up negative values so that the graphs can be plotted
    max_dev *= (max_dev > 0)
    min_dev *= (min_dev > 0)

    # Assume that all of them have the same binning
    elo, ehi, _, _ = get_errors(diff_graphs[0])
    xval = np.array(diff_graphs[0].GetX())

    return r.TGraphAsymmErrors(len(elo), xval, np.zeros_like(elo), elo, ehi,
                               min_dev, max_dev)
示例#13
0
def get_corrected_ratio(data, wsp, model, sym_uncer=False, dbg_file=None):
    """
    Get the corrected ratio in all bins
    """
    logging.info('Getting corrected ratio with {} errors'.
                 format('HESSE' if sym_uncer else 'MINOS'))
    corr_ratio = []
    # NOTE: Assuming here that the bins are ordered correctly AND that the
    for label, bounds in model.bins.iteritems():
        selections = []
        for ivar, var in enumerate(model.bin_cut_vars):
            selections.append(select_bin(var, *bounds[ivar]))
        bin_data = apply_selections(data, selections)

        chi1_prob, chi2_prob = get_state_fractions(bin_data, wsp, model, label)

        print_info('chi1', bin_data, chi1_prob)
        print_info('chi2', bin_data, chi2_prob)

        if dbg_file is not None:
            debug_plots('chi1_{}'.format(label), dbg_file, chi1_prob,
                        bin_data.corr_chi1, bin_data.chicMass)
            debug_plots('chi2_{}'.format(label), dbg_file, chi2_prob,
                        bin_data.corr_chi2, bin_data.chicMass)

        chi1_w = bin_data.loc[:, 'corr_chi1'] * chi1_prob
        chi2_w = bin_data.loc[:, 'corr_chi2'] * chi2_prob
        chi1_corr = np.sum(chi1_w)
        chi2_corr = np.sum(chi2_w)
        corr_ratio.append(chi2_corr / chi1_corr)

    # Assume that the relative uncertainties are unchanged for the corrected and
    # the uncorrected graph and use them to determine the uncertainties of the
    # corrected graph
    uncorr_graph = get_graph(wsp, model, 'r_chic2_chic1', sym_uncer)
    xlo, xhi, err_lo, err_hi = get_errors(uncorr_graph)
    xvals, yvals = np.array(uncorr_graph.GetX()), np.array(uncorr_graph.GetY())
    corr_ratio = np.array(corr_ratio)

    return r.TGraphAsymmErrors(len(corr_ratio), xvals, corr_ratio, xlo, xhi,
                               err_lo / yvals * corr_ratio,
                               err_hi / yvals * corr_ratio)
示例#14
0
def calc_chi2(graph, func):
    """
    Calculate the chi2 between the graph and all passed values of norm, lth and
    dlth (resp. kappa1 and kappa2)
    """
    logging.debug(
        'Calculating chi2 for graph \'{}\' and function \'{}\''.format(
            graph.GetName(), func.__name__))
    x_v = np.array(graph.GetX())
    ratio_v = np.array(graph.GetY())
    _, _, err_lo, err_hi = get_errors(graph)

    func_vals = func(x_v)

    # Again let numpy broadcasting to the lifting of getting everything into the
    # correct shapes. Since ratio_v and the error arrays are only 1 dimensional
    # this works perfectly
    diff = ratio_v[:, None] - func_vals
    err = (diff < 0) * err_hi[:, None] + (diff > 0) * err_lo[:, None]

    return np.sum((diff**2) / err**2, axis=0)
示例#15
0
def dump(graph, direction):
    """
    Dump the graph to a .tex table
    """
    x_vals = np.array(graph.GetX())
    y_vals = np.array(graph.GetY())
    xlo, xhi, ylo, yhi = get_errors(graph)

    x_lo, x_hi = x_vals - xlo, x_vals + xhi

    fmt_str = get_fmt_str(direction)

    for i, x in enumerate(x_vals):
        uncer_lo = '{:.4f}'.format(ylo[i])
        uncer_hi = '{:.4f}'.format(yhi[i])
        if uncer_lo == uncer_hi:
            uncer = '\pm {}'.format(uncer_lo)
        else:
            uncer = '{{}}^{{+{}}}_{{-{}}}'.format(uncer_hi, uncer_lo)

        print(fmt_str.format(x_lo[i], x_hi[i], x, y_vals[i], uncer))
def make_rel_diff_plot(graph_file, plot_config, variable):
    """
    Make the plot of the relative, scaled differences
    """
    rgraphs = get_variation_graphs(graph_file, '_scaled_rel_diff', plot_config)
    largest_d_graph = graph_file.Get('largest_dev_r_chic2_chic1')

    # To have the y-axis in percent
    rgraphs = [scale_graph(g, 100) for g in rgraphs]
    largest_d_graph = scale_graph(largest_d_graph, 100)

    _, _, ylo, yhi = get_errors(largest_d_graph)
    yran = np.max([np.abs(ylo), np.abs(yhi)])
    if yran > YRANGE_REL_DIFF[variable][1]:
        factor = 1.0
        while yran / factor > YRANGE_REL_DIFF[variable][1]:
            factor *= 2
        yran = [v * factor for v in YRANGE_REL_DIFF[variable]]
    else:
        yran = YRANGE_REL_DIFF[variable]

    leg = create_legend(0.675, 0.88, 0.16, plot_config, True)

    can = mkplot(shift_graphs(rgraphs, HORIZONTAL_SHIFT[variable], 0),
                 drawOpt='PLEX0', yRange=yran,
                 yLabel='scaled relative difference w.r.t. nominal [%]',
                 leg=leg, legEntries=[v[1] for v in plot_config['variations']],
                 **VAR_PLOT[variable])
    mkplot(largest_d_graph, can=can, drawOpt='sameE2',
           attr=LARGE_DEV_ATTR, leg=leg, legEntries=['largest deviation'],
           legOpt='F')
    x_range = VAR_PLOT[variable]['xRange']
    mkplot(r.TLine(0, 0, x_range[1], 0), can=can, drawOpt='same',
           attr=LINE_ATTR)

    return can
示例#17
0
def convert_graph(graph, direction):
    """
    Convert the TGraphAsymmErrors to the hepdata expected format

    See:
    https://hepdata-submission.readthedocs.io/en/latest/data_yaml.html
    """
    x_vals = np.array(graph.GetX())
    x_lo, x_hi, y_lo, y_hi = get_errors(graph)

    # number of digits after comma for bin-borders and bin-centers depends
    # on the angle under consideration
    fmt_bin = lambda x: int(round(x))
    fmt_cent = lambda x: round(x, 2)
    fmt_dep = lambda x: round(x, 4)
    if direction == 'costh':
        fmt_bin = lambda x: round(x, 4)
        fmt_cent = fmt_bin

    # Create the independent variable table in the format that hepdata expectes
    table = {}
    table['independent_variables'] = [{
        'header': {
            'name': direction,
            'units': ''
        },
        'values': []
    }]
    for cent, lo, hi in zip(x_vals, x_lo, x_hi):
        table['independent_variables'][0]['values'].append({
            'low':
            fmt_bin(cent - lo),
            'high':
            fmt_bin(cent + hi),
            'value':
            fmt_cent(cent)
        })

    # Create the dependent variable table
    table['dependent_variables'] = [{
        'header': {
            'name': 'chi_c2 over chi_c1 ratio'
        },
        'values': []
    }]
    y_vals = np.array(graph.GetY())

    for cent, lo, hi in zip(y_vals, y_lo, y_hi):
        table['dependent_variables'][0]['values'].append({
            'value':
            fmt_dep(cent),
            'errors': [
                # hepdata wants the minus sign in front of the lower errors
                {
                    'asymerror': {
                        'minus': -fmt_dep(lo),
                        'plus': fmt_dep(hi)
                    },
                    'label': 'stat'
                }
            ]
        })

    return table