def write_hist(hist_nano: ROOT.TH1D, category_dict: dict, name: str, isMC: bool = True): """ Make a new histogram for categorised events passing the cuts and write it to file Args: hist_nano : nanoAOD histogram category_dict : dictionary of category cuts name : category name isMC : flag for MC/data """ index_new = 0 hist_limits = ROOT.TH1D("hist", "hist", len(category_dict), 0, len(category_dict)) print(f"Writing hist {name}") for index, category in category_dict.items(): index_new += 1 hist_content = hist_nano.GetBinContent(hist_nano.FindBin(index)) hist_error = hist_nano.GetBinError(hist_nano.FindBin(index)) print(index, index_new, category, hist_content) hist_limits.SetBinContent(index_new, hist_content) hist_limits.SetBinError(index_new, hist_error) hist_limits.GetXaxis().SetBinLabel(index_new, category) if isMC: remove_neg_entries(hist_limits) hist_limits.SetTitle(name) hist_limits.SetName(name) hist_limits.SetDirectory(root_file) hist_limits.Write()
def remove_neg_entries(hist: ROOT.TH1D): """ Removes negative and/or small entries from a histogram """ alpha = 1. - 0.6827 upErr = ROOT.Math.gamma_quantile_c(alpha / 2, 1, 1) avgWeight = hist.Integral() / hist.GetEntries() if hist.GetEntries( ) > 0 else -1 #print "weight",avgWeight for ibin in range(hist.GetNbinsX()): c = hist.GetBinContent(ibin + 1) if c < 10**-4: hist.SetBinContent(ibin + 1, 10**-3) #note: in case of 0 entries the uncertainty is also small #(this is not the case with negative events) if hist.GetBinError(ibin + 1) < 10**-4 and avgWeight > 0: #set uncertainties for empy bins #https://twiki.cern.ch/twiki/bin/viewauth/CMS/PoissonErrorBars hist.SetBinError(ibin + 1, upErr * avgWeight) else: hist.SetBinError(ibin + 1, 10**-4)