5.6 Accessing Histogram Bins
Table of Contents
Finding bins
Once a histogram exists, its information is stored in discrete bins. To work with individual bins in code, you need to translate physical coordinates, such as an $x$ value, into bin numbers, or directly refer to bin indices.
For a one dimensional histogram like TH1F or TH1D, every bin has an integer index. You can retrieve the bin number that corresponds to a given $x$ position using the method
Int_t bin = h->FindBin(x);
Here h is a pointer to a histogram, and x is the coordinate in the histogram variable. The result bin is the index of the bin whose interval contains x.
ROOT also supports direct access using integer bin indices. The standard indexing convention is important:
Histogram bin index convention (TH1):
bin = 0is the underflow bin.bin = 1is the first visible bin.bin = nbinsis the last visible bin.bin = nbins + 1is the overflow bin.
Here nbins is the number of bins along the histogram axis.
To convert from bin number back to an $x$ coordinate, you can use
double xcenter = h->GetBinCenter(bin);
This returns the central value of the interval of that bin. You can also get the low or high edge of the bin intervals with
double xlow = h->GetBinLowEdge(bin);
and
double xup = xlow + h->GetBinWidth(bin);
or directly
double width = h->GetBinWidth(bin);
These functions are useful when you want to label points or when you loop over bins and need to know which physical range each bin represents.
For two dimensional histograms, such as TH2F or TH2D, ROOT uses a single global bin index internally, but you will usually work with separate indices for each axis. Each bin is identified by a pair of indices, binx and biny. To find the bin corresponding to a point $(x,y)$, use
Int_t binx = h2->GetXaxis()->FindBin(x);
Int_t biny = h2->GetYaxis()->FindBin(y);
To convert these into a global bin index that ROOT uses internally, call
Int_t bin = h2->GetBin(binx, biny);
You can also work directly with axis objects whenever you are primarily interested in the binning layout.
The same underflow and overflow convention exists for each axis in 2D and 3D histograms, so indices 0 and nbins+1 on any axis correspond to underflow and overflow in that dimension.
Reading bin contents
Once you know the bin number, you can read the content stored in that bin. For 1D histograms, you obtain the content by
double content = h->GetBinContent(bin);
Here content is typically the number of entries in the bin, possibly weighted if you filled the histogram with weights. The underflow and overflow bins are accessed through their indices according to the same convention. For example, to read the underflow bin content of a histogram with nbins bins:
- Underflow:
h->GetBinContent(0); - First regular bin:
h->GetBinContent(1); - Last regular bin:
h->GetBinContent(nbins); - Overflow:
h->GetBinContent(nbins + 1);
You can retrieve the statistical uncertainty on a bin in a similar way. If the histogram is configured to store sum of weights squared, then
double error = h->GetBinError(bin);
returns the bin error. If the histogram does not have Sumw2 enabled and is filled with unit weights, the error corresponds to the standard $\sqrt{N}$ counting uncertainty, where $N$ is the bin content.
For two dimensional histograms, there are two common patterns. You can either use the combined bin index, or work with axis indices. Using axis indices is often clearer:
double z = h2->GetBinContent(binx, biny);
ROOT will map the pair (binx, biny) internally to the correct global index. If you already calculated the global bin index bin using GetBin, then you can also call
double z = h2->GetBinContent(bin);
In both cases, z is the accumulated weight or entry count in that 2D bin.
When you need to inspect the full histogram programmatically, a typical pattern is to loop over all regular bins and read each bin content. For a 1D histogram, this means looping from 1 to nbins. For a 2D histogram, you would have nested loops over binx and biny, skipping or including underflow and overflow bins according to your analysis needs.
ROOT does not automatically protect you from accessing out of range bin indices. If you use a bin number smaller than 0 or larger than nbins+1, the result is undefined. You should always ensure that indices used in GetBinContent are in the valid range for the histogram and axis.
Changing bin contents
You can also modify bin contents directly. This is useful when you want to correct a single bin, initialize bins to a given value, perform custom reweighting, or create a histogram from precomputed data rather than by filling it with Fill.
To set the content of a single bin in a 1D histogram, use
h->SetBinContent(bin, value);
where value is the new numerical content you want to store. This completely replaces whatever was in that bin before.
If you also want to set the uncertainty on a bin explicitly, you can call
h->SetBinError(bin, error);
This sets the error used in fits and plotted error bars for that bin, independently of the bin content.
You can combine these operations with GetBinContent to apply transformations. For example, to double the contents of a given bin, you might read its content, modify it, and write it back:
double c = h->GetBinContent(bin);h->SetBinContent(bin, 2.0 * c);
A similar approach works for systematic reweighting of full histograms, implemented as loops over bin indices. When you do this, it is important to handle underflow and overflow bins consistently. If you want to modify only visible bins, loop from 1 to nbins. If you want to include underflow and overflow, extend the loop from 0 to nbins + 1.
For two dimensional histograms, you set and modify bin contents in an analogous way. You can use axis indices:
h2->SetBinContent(binx, biny, value);
and, if you have one, the global bin index
h2->SetBinContent(bin, value);
The same applies to setting errors with SetBinError.
Directly setting bin contents does not change the total number of entries reported by the histogram automatically in a way that always matches your analysis intent. ROOT keeps a separate counter of the number of entries, which is usually increased by calls to Fill. If you are constructing a histogram purely by manual SetBinContent calls, you may also want to adjust the reported number of entries with
h->SetEntries(nentries);
to keep metadata consistent with the actual bin contents. This is particularly relevant if the histogram will be used later for statistical calculations or fits that rely on the entry count.
Finally, remember that when you modify bin contents after a plot has been drawn, the changes will not appear until the canvas is updated. Calling gPad->Modified(); gPad->Update(); ensures that the drawing reflects your updated bin values.
Views: 13
KAHIBARO