예제 #1
0
def content_table(hnum, hden):
    table = []
    axis = 'recoil'
    try:
        hnum.axis(axis)
    except KeyError:
        axis = 'met'
    for x,ynum, yden in zip(hnum.axis(axis).identifiers(),hnum.values()[()],hden.values()[()]):
        eff =  ynum/ yden if yden != 0 else 0
        unc = clopper_pearson_interval(ynum, yden, 0.68)
        line = [(x.lo + x.hi)/2, ynum, yden, eff,unc[0], unc[1]]
        table.append(line)
    return tabulate(table, headers=['Recoil', 'Numerator', 'Denominator',"Efficiency", "Eff-sigma","Eff+sigma"])
예제 #2
0
def test_clopper_pearson_interval():
    from coffea.hist.plot import clopper_pearson_interval

    # Reference values for CL=0.6800 calculated with ROOT's TEfficiency
    num = np.array([1., 5., 10., 10.])
    denom = np.array([10., 10., 10., 437.])
    ref_hi = np.array([0.293313782248242, 0.6944224231766912, 1.0, 0.032438865381336446])
    ref_lo = np.array([0.01728422272382846, 0.3055775768233088, 0.8325532074018731, 0.015839046981153772])

    interval = clopper_pearson_interval(num, denom, coverage=0.68)

    threshold = 1e-6
    assert(all((interval[1, :] / ref_hi) - 1 < threshold))
    assert(all((interval[0, :] / ref_lo) - 1 < threshold))
예제 #3
0
    pileup_corr_puDown = lookup_tools.dense_lookup.dense_lookup(
        corr_puDown, fin_pileup["pileup"].edges)

corrections['2018_pileupweight'] = pileup_corr
corrections['2018_pileupweight_puUp'] = pileup_corr_puUp
corrections['2018_pileupweight_puDown'] = pileup_corr_puDown

with uproot.open(
        "correction_files/RUNTriggerEfficiencies_SingleMuon_Run2016_V2p1_v03.root"
) as fin:
    denom = fin[
        "DijetTriggerEfficiencySeveralTriggers/jet1SoftDropMassjet1PtDenom_cutJet"]
    num = fin[
        "DijetTriggerEfficiencySeveralTriggers/jet1SoftDropMassjet1PtPassing_cutJet"]
    eff = num.values / np.maximum(denom.values, 1)
    efferr = plot.clopper_pearson_interval(num.values, denom.values)
    msd_bins, pt_bins = num.edges
    # Cut pt < 200
    cutpt = pt_bins >= 200
    pt_bins = pt_bins[cutpt]
    cutpt = cutpt[:-1]
    eff = eff[:, cutpt]
    eff_trigweightDown = efferr[0, :, cutpt]
    eff_trigweightUp = efferr[1, :, cutpt]

corrections['2016_trigweight_msd_pt'] = lookup_tools.dense_lookup.dense_lookup(
    eff, (msd_bins, pt_bins))
corrections[
    '2016_trigweight_msd_pt_trigweightDown'] = lookup_tools.dense_lookup.dense_lookup(
        eff_trigweightDown, (msd_bins, pt_bins))
corrections[
예제 #4
0
def plotratio(
    num,
    denom,
    ax=None,
    clear=True,
    overflow=False,
    error_opts=None,
    denom_fill_opts=None,
    guide_opts=None,
    unc="clopper-pearson",
    label=None,
    ratio_yticks=[],  # [start, stop, step] -> [0.5, 1.5, 0.1]
):
    if ax is None:
        fig, ax = plt.subplots(1, 1)
    else:
        if not isinstance(ax, plt.Axes):
            raise ValueError("ax must be a matplotlib Axes object")
        if clear:
            ax.clear()

    if error_opts is None and denom_fill_opts is None and guide_opts is None:
        error_opts = {}
        denom_fill_opts = {}

    (naxis,) = num.axes
    (daxis,) = denom.axes
    assert isinstance(naxis, (hist.axis.Regular, hist.axis.Variable))
    assert isinstance(daxis, (hist.axis.Regular, hist.axis.Variable))
    assert all(naxis.edges == daxis.edges)

    ax.set_xlabel(naxis.label)
    ax.set_ylabel("Ratio")
    edges = naxis.edges
    centers = naxis.centers

    sumw_num = num.view(flow=overflow)["value"]
    sumw2_num = num.view(flow=overflow)["variance"]
    sumw_denom = denom.view(flow=overflow)["value"]
    sumw2_denom = denom.view(flow=overflow)["variance"]

    rsumw = sumw_num / sumw_denom
    if unc == "clopper-pearson":
        rsumw_err = np.abs(clopper_pearson_interval(sumw_num, sumw_denom) - rsumw)
    elif unc == "poisson-ratio":
        # poisson ratio n/m is equivalent to binomial n/(n+m)
        rsumw_err = np.abs(clopper_pearson_interval(sumw_num, sumw_num + sumw_denom) - rsumw)
    elif unc == "num":
        rsumw_err = np.abs(poisson_interval(rsumw, sumw2_num / sumw_denom ** 2) - rsumw)
    elif unc == "normal":
        rsumw_err = np.abs(normal_interval(sumw_num, sumw_denom, sumw2_num, sumw2_denom))
    else:
        raise ValueError("Unrecognized uncertainty option: %r" % unc)

    if error_opts is not None:
        opts = {"label": label, "linestyle": "none"}
        opts.update(error_opts)
        emarker = opts.pop("emarker", "")
        errbar = ax.errorbar(x=centers, y=rsumw, yerr=rsumw_err, **opts)
        plt.setp(errbar[1], "marker", emarker)
    if denom_fill_opts is not None:
        unity = np.ones_like(sumw_denom)
        denom_unc = poisson_interval(unity, sumw2_denom / sumw_denom ** 2)
        opts = {"step": "post", "facecolor": (0, 0, 0, 0.3), "linewidth": 0}
        opts.update(denom_fill_opts)
        ax.fill_between(
            edges,
            np.r_[denom_unc[0], denom_unc[0, -1]],
            np.r_[denom_unc[1], denom_unc[1, -1]],
            **opts,
        )
    if guide_opts is not None:
        opts = {"linestyle": "--", "color": (0, 0, 0, 0.5), "linewidth": 1}
        opts.update(guide_opts)
        ax.axhline(1.0, **opts)

    if ratio_yticks:
        start, stop, step = ratio_yticks
        ax.set_yticks(np.arange(start, stop + step, step).tolist())
        for label in ax.yaxis.get_ticklabels()[::2]:
            label.set_visible(False)
        ax.set_ylim(start, stop)

    if clear:
        ax.autoscale(axis="x", tight=True)
        ax.set_ylim(0, None)

    return ax