def geterrorband(*hists, **kwargs): """Make an error band histogram for a list of histograms, or stack. Returns an TGraphAsymmErrors object.""" verbosity = LOG.getverbosity(kwargs) hists = unwraplistargs(hists) hists = [ h.GetStack().Last() if isinstance(h, THStack) else h for h in hists ] sysvars = kwargs.get( 'sysvars', []) # list of tuples with up/cent/down variation histograms name = kwargs.get('name', None) or "error_" + hists[0].GetName() title = kwargs.get( 'title', None) or ("Sys. + stat. unc." if sysvars else "Stat. unc.") color = kwargs.get('color', kBlack) hist0 = hists[0] nbins = hist0.GetNbinsX() if sysvars and isinstance(sysvars, dict): sysvars = [v for k, v in sysvars.iteritems()] error = TGraphAsymmErrors() error.SetName(name) error.SetTitle(title) LOG.verb("geterrorband: Making error band for %s" % (hists), verbosity, 2) TAB = LOG.table( "%5s %7s %6s %10s %11s %-20s %-20s %-20s", "%5d %7.6g %6.6g %10.2f %11.2f +%8.2f -%8.2f +%8.2f -%8.2f +%8.2f -%8.2f", verb=verbosity, level=3) TAB.printheader("ibin", "xval", "xerr", "nevts", "sqrt(nevts)", "statistical unc.", "systematical unc.", "total unc.") ip = 0 for ibin in range(1, nbins + 1): xval = hist0.GetXaxis().GetBinCenter(ibin) xerr = 0 if ibin in [0, nbins + 1] else hist0.GetXaxis().GetBinWidth(ibin) / 2 yval = 0 statlow2, statupp2 = 0, 0 syslow2, sysupp2 = 0, 0 for hist in hists: # STATISTICS yval += hist.GetBinContent(ibin) statlow2 += hist.GetBinErrorLow(ibin)**2 statupp2 += hist.GetBinErrorUp(ibin)**2 for histup, hist, histdown in sysvars: # SYSTEMATIC VARIATIONS syslow2 += (hist.GetBinContent(ibin) - histdown.GetBinContent(ibin))**2 sysupp2 += (hist.GetBinContent(ibin) - histup.GetBinContent(ibin))**2 ylow2, yupp2 = statlow2 + syslow2, statupp2 + sysupp2, error.SetPoint(ip, xval, yval) error.SetPointError(ip, xerr, xerr, sqrt(ylow2), sqrt(yupp2)) TAB.printrow(ibin, xval, xerr, yval, sqrt(abs(yval)), sqrt(statupp2), sqrt(statlow2), sqrt(sysupp2), sqrt(syslow2), sqrt(yupp2), sqrt(ylow2)) ip += 1 seterrorbandstyle(error, color=color) #error.SetLineColor(hist0.GetLineColor()) error.SetLineWidth(hist0.GetLineWidth()) # use draw option 'E2 SAME' return error
def close(*hists,**kwargs): """Close histograms.""" verbosity = LOG.getverbosity(kwargs) hists = unwraplistargs(hists) for hist in hists: if isinstance(hist,THStack): if verbosity>1: print '>>> close: Deleting histograms from stack "%s"...'%(hist.GetName()) for subhist in hist.GetStack(): deletehist(subhist,**kwargs) deletehist(hist,**kwargs) else: deletehist(hist,**kwargs)
def normalize(*hists, **kwargs): """Normalize histogram(s).""" hists = unwraplistargs(hists) scale = kwargs.get('scale', None) or 1.0 for hist in hists: if hist.GetBinErrorOption() == TH1.kPoisson: hist.SetBinErrorOption(TH1.kNormal) hist.Sumw2() integral = hist.Integral() if integral: hist.Scale(scale / integral) else: LOG.warning("norm: Could not normalize; integral = 0!")
def expanddas(*datasets, **kwargs): """Get full list of datasets for a list of DAS dataset patterns.""" verbosity = kwargs.get('verb', 0) if verbosity >= 1: print ">>> expanddas(%r)" % (datasets) datasets = unwraplistargs(datasets) for dataset in datasets[:]: if '*' not in dataset: continue index = datasets.index(dataset) query = "dataset=%s" % (dataset) if dataset.endswith('USER'): query += " instance=prod/phys03" subset = dasgoclient(query, verb=verbosity).split('\n') datasets.remove(dataset) for i, subdataset in enumerate(subset): datasets.insert(index + 1, subdataset) datasets.sort() return datasets
def deletehist(*hists,**kwargs): """Completely remove histograms from memory.""" verbosity = LOG.getverbosity(kwargs) hists = unwraplistargs(hists) for hist in hists: hclass = hist.__class__.__name__ hname = hist.GetName() if hasattr(hist,'GetName') else None LOG.verb("deletehist: deleting %s %r"%(hclass,hname or hist),verbosity,3) #try: if hist: if hasattr(hist,'GetDirectory') and hist.GetDirectory()==None: hist.Delete() elif hname: gDirectory.Delete(hist.GetName()) else: LOG.warning("deletehist: %s %s has no name!"%(hclass,hist)) else: LOG.warning("deletehist: %s is already %s"%(hclass,hist)) #except AttributeError: # print ">>> AttributeError: " # raise AttributeError del hist
def addoverflow(*hists, **kwargs): """Add overflow to last bin(s).""" verbosity = LOG.getverbosity(kwargs) hists = unwraplistargs(hists) merge = kwargs.get( 'merge', False) # merge last and overflow bin(s), otherwise reset to 0 LOG.verbose( "addoverflow: %r (merge=%r)" % ("', '".join(h.GetName() for h in hists), merge), verbosity, 2) for hist in hists: LOG.verbose("addoverflow: %r" % (hist.GetName()), verbosity, 3) if isinstance(hist, TH2): nxbins = hist.GetXaxis().GetNbins() nybins = hist.GetYaxis().GetNbins() bins = [(ix,nybins) for ix in range(1,nxbins)] +\ [(nxbins,iy) for iy in range(1,nybins)] + [(nxbins,nybins)] for xbin, ybin in bins: yval = hist.GetBinContent(xbin, ybin) # last bin yerr2 = hist.GetBinError(xbin, ybin)**2 # last bin ofbins = [] # 1 or 3 overflow bins if xbin == nxbins: ofbins.append((xbin + 1, ybin)) # add overflow in x if ybin == nybins: ofbins.append((xbin, ybin + 1)) # add overflow in y if xbin == nxbins and ybin == nybins: ofbins.append((xbin + 1, ybin + 1)) for xof, yof in ofbins: yval += hist.GetBinContent(xof, yof) # overflow yerr2 += hist.GetBinError(xof, yof)**2 # overflow yerr = sqrt(yerr2) LOG.verbose( "addoverflow: bin (%d,%d): %7.2f +- %6.2f -> %7.2f +- %6.2f" % (xbin, ybin, hist.GetBinContent(xbin, ybin), hist.GetBinError(xbin, ybin), yval, yerr), verbosity, 3) hist.SetBinContent(xbin, ybin, yval) hist.SetBinError(xbin, ybin, yerr) # add in quadrature if merge: # merge last and overflow bin(s) for xof, yof in ofbins: hist.SetBinContent(xof, yof, yval) hist.SetBinError(xof, yof, sqrt(yerr2)) else: # reset to 0 for xof, yof in ofbins: hist.SetBinContent(xof, yof, 0) hist.SetBinError(xof, yof, 0) else: nbins = hist.GetXaxis().GetNbins() yval = hist.GetBinContent(nbins) # last bin yerr2 = hist.GetBinError(nbins)**2 # last bin yval += hist.GetBinContent(nbins + 1) # overflow yerr2 += hist.GetBinError(nbins + 1)**2 # overflow yerr = sqrt(yerr2) LOG.verbose( "addoverflow: bin %d: %7.2f +- %6.2f -> %7.2f +- %6.2f" % (nbins, hist.GetBinContent(nbins), hist.GetBinError(nbins), yval, yerr), verbosity, 3) hist.SetBinContent(nbins, yval) hist.SetBinError(nbins, yerr) # add in quadrature if merge: # merge last and overflow bin(s) hist.SetBinContent(nbins + 1, yval) hist.SetBinError(nbins + 1, sqrt(yerr2)) else: # reset to 0 hist.SetBinContent(nbins + 1, 0) # reset hist.SetBinError(nbins + 1, 0) return hists