KAHIBARO
Discord Login Register

6.4. Projections

Table of Contents

ProjectionX

A two dimensional histogram in ROOT, such as a TH2F or TH2D, stores counts in bins that are arranged on an X grid and a Y grid. A projection is a way to reduce this 2D information to a 1D histogram by summing over one axis and keeping the binning of the other axis. This is very common in analysis, for example when you want to look at the distribution of X values for a selected Y range.

ROOT provides member functions of TH2 to do this. To project a 2D histogram onto the X axis you use the method ProjectionX. The general idea is that you select a range of Y bins and for each X bin ROOT sums the contents of all selected Y bins. The result is a TH1 histogram whose X binning is identical to the original TH2, while the Y information has been integrated out.

In its most common form, you call:

cpp
TH1D *hx = h2->ProjectionX();

where h2 is a pointer to a TH2 histogram. This creates a new 1D histogram that contains, for each X bin index $i$, the sum
$$
N_i = \sum_{j=\text{all Y bins}} n_{ij},
$$
where $n_{ij}$ is the content of the bin with X index $i$ and Y index $j$. The bin errors are combined in quadrature, so the error of each X bin in the projection is
$$
\sigma_i = \sqrt{\sum_{j} \sigma_{ij}^2}.
$$

A projection histogram is a new histogram, independent of the original TH2. You are responsible for keeping a pointer to it and for writing it to a file or deleting it when you no longer need it.

Often you do not want to use the full Y range. For example you may have a correlation of energy vs position, and you are only interested in a strip of Y values. In that case you use the form

cpp
TH1D *hx = h2->ProjectionX("hx", ybin_min, ybin_max);

Here ybin_min and ybin_max are bin indices along the Y axis, not coordinate values. This projection keeps all X bins, but for each X bin it sums Y bins from ybin_min to ybin_max inclusive.

A practical workflow is to first decide the Y coordinate range you care about, then convert that to bin indices using the axis helper functions:

cpp
int ybin_min = h2->GetYaxis()->FindBin(ymin);
int ybin_max = h2->GetYaxis()->FindBin(ymax);
TH1D *hx = h2->ProjectionX("hx", ybin_min, ybin_max);

Now hx contains the X distribution for events where the original Y value lay between ymin and ymax. You can immediately draw it on a canvas with:

cpp
hx->Draw();

ROOT also lets you control whether underflow and overflow bins of the selected Y range are included, and whether bin labels are transferred, using additional options in ProjectionX. For most introductory use you can rely on the default behavior, which uses only the normal Y bins you specify.

A common pattern is to create several projections for different Y slices and compare them. You might write:

cpp
int y1_min = h2->GetYaxis()->FindBin(0.0);
int y1_max = h2->GetYaxis()->FindBin(1.0);
TH1D *hx1 = h2->ProjectionX("hx1", y1_min, y1_max);
int y2_min = h2->GetYaxis()->FindBin(1.0);
int y2_max = h2->GetYaxis()->FindBin(2.0);
TH1D *hx2 = h2->ProjectionX("hx2", y2_min, y2_max);

You can then draw hx1 and hx2 on the same canvas to see how the X distribution changes with Y.

The key points are that ProjectionX keeps the X axis and integrates over Y, that you choose Y ranges using bin indices or by converting from coordinate values with FindBin, and that the result is an ordinary 1D histogram which you can analyze with all the standard TH1 tools.

ProjectionY

ProjectionY is the complementary operation. It produces a 1D histogram along the Y axis by summing over selected X bins. You use it when you want to study how Y is distributed, either for the full X range or only for a restricted X interval.

The simplest call is:

cpp
TH1D *hy = h2->ProjectionY();

This builds a TH1 whose Y binning is identical to that of the parent TH2. For each Y bin index $j$, it stores
$$
M_j = \sum_{i=\text{all X bins}} n_{ij},
$$
with errors combined in quadrature, in exactly the same way as for ProjectionX.

To restrict the projection to a given X range you give explicit X bin indices:

cpp
TH1D *hy = h2->ProjectionY("hy", xbin_min, xbin_max);

Again, xbin_min and xbin_max refer to bin numbers along the X axis. In most analyses you will want to define those using axis coordinates:

cpp
int xbin_min = h2->GetXaxis()->FindBin(xmin);
int xbin_max = h2->GetXaxis()->FindBin(xmax);
TH1D *hy = h2->ProjectionY("hy", xbin_min, xbin_max);

Now hy represents the Y distribution for events that have X between xmin and xmax in the original 2D histogram. You can visualize it with:

cpp
hy->Draw();

Just like ProjectionX, ProjectionY creates new histograms that you manage yourself. This means you can safely modify them, for example by rebinning or fitting, without affecting the original TH2. It is common to use ProjectionY to get 1D slices of a 2D distribution and then fit peaks or measure means in each slice.

For example, suppose h2 contains time vs energy. To study the time distribution for three different energy intervals you might write:

cpp
int e1_min = h2->GetXaxis()->FindBin(0.0);
int e1_max = h2->GetXaxis()->FindBin(1.0);
TH1D *ht1 = h2->ProjectionY("ht1", e1_min, e1_max);
int e2_min = h2->GetXaxis()->FindBin(1.0);
int e2_max = h2->GetXaxis()->FindBin(2.0);
TH1D *ht2 = h2->ProjectionY("ht2", e2_min, e2_max);

You can then fit each projected histogram with a function or compare their means and widths.

In summary, ProjectionY keeps the Y axis and integrates away the X axis over a selectable bin range. Together, ProjectionX and ProjectionY are basic tools for extracting 1D information from 2D histograms and are used heavily in analysis to study slices, marginal distributions, and correlations from different views.

Views: 12

Comments

Please login to add a comment.

Don't have an account? Register now!