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"])
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))
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[
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