def make_hist_from_dict_of_counts(values, var_type, hist_label, log='', xmin_force=0.0, xmax_force=0.0, normalize=False, sort=False): """ Fill a histogram with values from a dictionary (each key will correspond to one bin) """ assert var_type == 'int' or var_type == 'string' # floats should be handled by Hist class in hist.py if len(values) == 0: print 'WARNING no values for %s in make_hist' % hist_label return TH1D(hist_label, '', 1, 0, 1) bin_labels = sorted(values) if not sort and var_type == 'string': # for strings, sort so most common value is to left side bin_labels = sorted(values, key=values.get, reverse=True) if var_type == 'string': n_bins = len(values) else: n_bins = bin_labels[-1] - bin_labels[0] + 1 hist = None xbins = [0. for _ in range(n_bins+1)] # NOTE the +1 is 'cause you need the lower edge of the overflow bin if xmin_force == xmax_force: # if boundaries aren't set explicitly, work out what they should be if var_type == 'string': set_bins(bin_labels, n_bins, 'x' in log, xbins, var_type) hist = Hist(n_bins, xbins[0], xbins[-1], xbins=xbins) else: hist = Hist(n_bins, bin_labels[0] - 0.5, bin_labels[-1] + 0.5) # for integers, just go from the first to the last bin label (they're sorted) else: hist = Hist(n_bins, xmin_force, xmax_force) for ival in range(len(values)): if var_type == 'string': label = bin_labels[ival] ibin = ival + 1 else: label = '' ibin = hist.find_bin(bin_labels[ival]) hist.set_ibin(ibin, values[bin_labels[ival]], error=math.sqrt(values[bin_labels[ival]]), label=label) # make sure there's no overflows if hist.bin_contents[0] != 0.0 or hist.bin_contents[-1] != 0.0: for ibin in range(hist.n_bins + 2): print '%d %f %f' % (ibin, hist.low_edges[ibin], hist.bin_contents[ibin]) raise Exception('overflows in ' + hist_label) if normalize: hist.normalize() hist.ytitle = 'freq' else: hist.ytitle = 'counts' roothist = make_hist_from_my_hist_class(hist, hist_label) return roothist
def make_hist_from_dict_of_counts(values, var_type, hist_label, log='', xmin_force=0.0, xmax_force=0.0, normalize=False, sort=False): """ Fill a histogram with values from a dictionary (each key will correspond to one bin) """ assert var_type == 'int' or var_type == 'string' # floats should be handled by Hist class in hist.py if len(values) == 0: print 'WARNING no values for %s in make_hist' % hist_label return Hist(1, 0, 1) bin_labels = sorted(values) if not sort and var_type == 'string': # for strings, sort so most common value is to left side bin_labels = sorted(values, key=values.get, reverse=True) if var_type == 'string': n_bins = len(values) else: n_bins = bin_labels[-1] - bin_labels[0] + 1 hist = None xbins = [0. for _ in range(n_bins+1)] # NOTE the +1 is 'cause you need the lower edge of the overflow bin if xmin_force == xmax_force: # if boundaries aren't set explicitly, work out what they should be if var_type == 'string': set_bins(bin_labels, n_bins, 'x' in log, xbins, var_type) hist = Hist(n_bins, xbins[0], xbins[-1], xbins=xbins) else: hist = Hist(n_bins, bin_labels[0] - 0.5, bin_labels[-1] + 0.5) # for integers, just go from the first to the last bin label (they're sorted) else: hist = Hist(n_bins, xmin_force, xmax_force) for ival in range(len(values)): if var_type == 'string': label = bin_labels[ival] ibin = ival + 1 else: label = '' ibin = hist.find_bin(bin_labels[ival]) hist.set_ibin(ibin, values[bin_labels[ival]], error=math.sqrt(values[bin_labels[ival]]), label=label) # make sure there's no overflows if hist.bin_contents[0] != 0.0 or hist.bin_contents[-1] != 0.0: for ibin in range(hist.n_bins + 2): print '%d %f %f' % (ibin, hist.low_edges[ibin], hist.bin_contents[ibin]) raise Exception('overflows in ' + hist_label) if normalize: hist.normalize() hist.ytitle = 'freq' else: hist.ytitle = 'counts' return hist