Setting and getting a bin content for TH1D and TProfile

Dear Root Experts,

Is there any good reason that method SetBinContent() (or GetBinContent()) is behaving differently when used for TH1D or TProfile object?

This simple example illustrates (I was expecting to get in both cases 440 as an output):

root [0] TH1D *hist = new TH1D("histName","histTitle",1,0,1) root [1] hist->SetBinContent(1,440) root [2] hist->GetBinContent(1) (const Double_t)4.40000000000000000e+02 root [3] TProfile *profile = new TProfile("profileName","profileTitle",1,0,1) root [4] profile->SetBinContent(1,440) root [5] profile->GetBinContent(1) (const Double_t)0.00000000000000000e+00 root [6]

Cheers,
Ante

P.S. ROOT 5.25/01 (trunk@30245, Sep 18 2009, 13:51:11 on linuxx8664gcc)

Hi,
a TProfile displays the average values in y with respect to x.
SetBinContent on a TProfile does not make then much sense.
You should use Fill for filling the contents of a profile. If you have already the y values and the errors, then you should use directly an histogram.

Best Regards

Lorenzo

Hi Lorenzo,

Perhaps an extreme/naive example, but I have it in my analysis - it illustrates the difference and the resulting bug I eventually got in my code:

I use TProfile named “Flags” to store in each bin Boolean, where each Boolean flags certain setting (e.g. if I have used in the analysis particle weights or not, if I have applied correction for non-uniform acceptance or not, etc). I run on the local cluster, so at the end of the day I am merging the output *.root files.

If I would have used TH1D to store these flags, than after the merging they would be just summed up, and I would have to take additional care in my code to correct for this.

So I straightforwardly used SetBinContent() for TProfile just to set content of a bin to either 0 or 1, but as I already reported I was always in this way actually setting 0, which turned out to be a bug in my code.

I can of course use method Fill() for this purpose, and this is what I eventually did.

Cheers,
Ante

I am not sure I have understood your use case, in particular what your variable y is.

You can also average histogram using TH1::Add, see

root.cern.ch/root/htmldoc/TH1.html#TH1:Add

Hi Lorenzo,

I want to use TProfile to store Booleans (so in each bin is either 0 or 1), so that after merging I still automatically have in each bin 0 or 1. (I used SetBinLabel() to record which Boolean flag is in which bin.)

The point is that after I have run over data on the cluster AND after the merging is performed at the end of the day, by accessing this TProfile holding Boolean flags I can immediately trace back the settings I used to run over data.

Than depending on those settings my analysis will be performed differently on the large statistics, merged output file, to get the final results.

Thanks for your replies,
Ante

Hi,

then in your special case TH1::Add using the option to average should work too. Otherwise a TProfile will work too suing the Fill method. SetBinContent will work only if you are calling afterwards SetBinEntries(bin,1).

Best Regards

Lorenzo

Hi Lorenzo,

This is what I have now in my code and this works perfectly fine.

This is precisely what I have missed in my original code and which eventually yielded a bug.

Thanks a lot for your replies,
Ante

Dear all.

There’s a function f=f(i,j), i,j integers. For a j fixed value in a set { j }, I have TProfile histograms of f vs i, let’s call it hprof_j.

The binning is the same for all hprof_j: same number of bins, nBins_i, and same extreme values in i-axis, i_min and i_max, so we have the same bin number associated with the same value in i-axis for all hprof_j.

Those hprof_j is the information I have.

Now, if we imagine an j-axis perperdicular to i-axis, we can vizualise a TProfile2d, with f vs (i,j). I would like to do two things:

a) Define a TProfile2d, hprof2d, with the same number of bins in i-axis, nBins_i, and same extreme values in i-axis, i_min and i_max, and with nBins_j and j_min, j_max in j-axis.

b) In a loop over j, get the BinEntries, BinContents and BinErrors (in this order) from hprof_j at a given i value in i-axis (another internal loop here over bins in i-axis), and then set the same content, entries and errors for the bin at the coordinate (i,j) ----> f vs (i,j)

c) At the end of the routine, there should be a TProfile2d that for j fixed, gives an identical TProfile as the hprof_j.

  1. This is the most important thing I’d like to do: I’d like to obtain a set of hprof_i, so that for a i fixed value, I have a TProfile, f vs j.

a) Define a TProfile, hprof_i, i fixed value, with nBins_j and j_min, j_max.

b) Something like this: to have a vector of all hprof_j. Loop over j, take a hprof_j and get BinEntries, BinContents and BinErrors at i value in i-axis of hprof_j, and then set those values for bin at value j in j-axis of hprof_i just defined.

c) End up with set of hprof_i, f vs j.

Now, the PROBLEM:

Just to try out the TProfile::GetBinEntries(), TProfile::GetBinContent(), TProfile::GetBinError(), TProfile::SetBinEntries(), TProfile::SetBinContent(), TProfile::SetBinError(), I created a TProfile hprof which I filled and then created an empty one, hprof2.

The idea is to make hprof2 the exact profile hist. than hprof by using the SetBin* and GetBin* methods. However, it does not work.

The problem here, is that I just have as information the BinContent, BinError and BinEntries from the hprof_j’s, but I do not have the actual entries values with which hprof_j were filled, so I cannot use TProfile::Fill() to fill hprof_i just respecting coordinates.

Any ideas?

I attach a macro that illustrates the problem.

Thanks in advance!!!
Daniel
example.C (2.36 KB)