Bin contents depends on total number of bins

Hi,

I have been staring myself blind over this, maybe it’s something very obvious but I don’t see it.
I fill three different histograms, but with the same data… The binsize is the same for each of the histograms, only the number of bins is different for each histogram. For the third histogram, some values might actually larger than the upper bound of the histo (in which case I don’t fill the histogram).
Both in the plots as when I print out the bin contents of each histogram, however, are different for histogram “h3” compared to h1 or h2.

Any help would be very much appreciated.
The (simplified) code:


void Main()
{
	std::ifstream ffile( "exampledebug.dat" );
	
	double delta = 0.010;

	int nbins1 = 11; 
	TH1D* h1 = new TH1D("h1", "sum E dep. of all 3x3 pixels (MeV)" , nbins1, 0.0, nbins1*delta );
	int nbins2 = 14; 
	TH1D* h2 = new TH1D("h2", "sum E dep. of all 3x3 pixels (MeV)" , nbins2, 0.0, nbins2*delta );
	int nbins3 = 9; 
	TH1D* h3 = new TH1D("h3", "sum E dep. of all 3x3 pixels (MeV)" , nbins3, 0.0, nbins3*delta );

cout << "MAX VALUES: " << nbins1*delta << " " << nbins2*delta << " " << nbins3*delta << " " << endl;

	double sumE;
	int count0(0), count1(0), count2(0);
	while ( !ffile.eof() )
	{
		ffile >> sumE; 
		if ( !ffile.eof() )
		{
			if (sumE > 0.0 && sumE < nbins1*delta)
			{
				h1->Fill(sumE); 
				count0++;
			}
			if (sumE > 0.0 && sumE < nbins2*delta)
			{
				h2->Fill(sumE); 
				count1++;
			}
			if (sumE > 0.0 && sumE < nbins3*delta)
			{
				h3->Fill(sumE); 
				count2++;
			}
		}
	}
	cout << "FILL COUNTS: " << count0 << " " << count1 << " " << count2 << endl;

	TCanvas* debug = new TCanvas("debug", "", 1500, 500);
	debug->Divide(3, 1);
	debug->cd(1);
	h1->Draw(); 
	debug->cd(2);
	h2->Draw(); 
	debug->cd(3);
	h3->Draw(); 

	// ------------
		int totCont(0);
		cout << "SUM_E, nbins1: " << nbins1 << endl;
		for (int ibin = 1; ibin <= nbins1; ibin++)
		{
		 	int cont = h1->GetBinContent( ibin );
			cout << "[" << ibin << "]: " << cont << " " 
			 	 << " lower edge: " << h1->GetBinLowEdge(ibin) << endl;
			totCont += cont;
		}
		cout << "    TOT: " << totCont << endl;
		// -------------------------------------
		totCont = 0;
		cout << "SUM_E, nbins2: " << nbins2 << endl;
		for (int ibin = 1; ibin <= nbins2; ibin++)
		{
		 	int cont = h2->GetBinContent( ibin );
			cout << "[" << ibin << "]: " << cont << " "  
			 	 << " lower edge: " << h2->GetBinLowEdge(ibin) << endl;
			totCont += cont;
		}
		cout << "    TOT: " << totCont << endl;
		// -------------------------------------
		totCont = 0;
		cout << "SUM_E, nbins3: " << nbins3 << endl;
		for (int ibin = 1; ibin <= nbins3; ibin++)
		{
		 	int cont = h3->GetBinContent( ibin );
			cout << "[" << ibin << "]: " << cont << " "  
			 	 << " lower edge: " << h3->GetBinLowEdge(ibin) << endl;
			totCont += cont;
		}
		cout << "    TOT: " << totCont << endl;
}

The output I get is:

root [1] Main()
MAX VALUES: 0.11 0.14 0.09 
FILL COUNTS: 575936 578793 80398
SUM_E, nbins1: 11
[1]: 0  lower edge: 0
[2]: 9717  lower edge: 0.01
[3]: 3384  lower edge: 0.02
[4]: 395  lower edge: 0.03
[5]: 1529  lower edge: 0.04
[6]: 3067  lower edge: 0.05
[7]: 11676  lower edge: 0.06
[8]: 34030  lower edge: 0.07
[9]: 72799  lower edge: 0.08
[10]: 122622  lower edge: 0.09
[11]: 316717  lower edge: 0.1
    TOT: 575936
SUM_E, nbins2: 14
[1]: 0  lower edge: 0
[i][2]: 9717  lower edge: 0.01[/i]
[b][3]: 3384  lower edge: 0.02[/b]
[b][4]: 395  lower edge: 0.03[/b]
[i][5]: 1529  lower edge: 0.04[/i]
[b][6]: 3067  lower edge: 0.05[/b]
[b][7]: 11676  lower edge: 0.06[/b]
[i][8]: 34030  lower edge: 0.07[/i]
[b][9]: 72799  lower edge: 0.08[/b]
[10]: 122622  lower edge: 0.09
[11]: 316717  lower edge: 0.1
[12]: 2856  lower edge: 0.11
[13]: 0  lower edge: 0.12
[14]: 1  lower edge: 0.13
    TOT: 578793
SUM_E, nbins3: 9
[1]: 0  lower edge: 0
[i][2]: 9717  lower edge: 0.01[/i]
[b][3]: 0  lower edge: 0.02[/b]
[b][4]: 3779  lower edge: 0.03[/b]
[i][5]: 1529  lower edge: 0.04[/i]
[b][6]: 1538  lower edge: 0.05[/b]
[b][7]: 13205  lower edge: 0.06[/b]
[i][8]: 34030  lower edge: 0.07[/i]
[b][9]: 16600  lower edge: 0.08[/b]
    TOT: 80398

Note, how bins 3, 4, 6, 7 and 9 for h3 are different from h1 and h2, but bin 2, 5 and 8 are equal.


If your “exampledebug.dat” file contains values which are “exactly” equal to “i0.01" then, due to floating-point rounding problems, they may enter either into the histogram’s bin which begins with "i0.01” or which ends with “i*0.01” (note that, in the verbose screen output, you just see the leading several decimal places of the “lower edges”).
Try, for example (even shifting by something like +1e-11 instead of +0.5 should be sufficient): TH1D* h1 = new TH1D("h1", "sum E dep. of all 3x3 pixels (MeV)" , nbins1, 0.0 + 0.5 * delta, nbins1*delta + 0.5 * delta ); TH1D* h2 = new TH1D("h2", "sum E dep. of all 3x3 pixels (MeV)" , nbins2, 0.0 + 0.5 * delta, nbins2*delta + 0.5 * delta ); TH1D* h3 = new TH1D("h3", "sum E dep. of all 3x3 pixels (MeV)" , nbins3, 0.0 + 0.5 * delta, nbins3*delta + 0.5 * delta );
See also: Different Values on cout and TH2

Hi Pepe,

Thanks for your reply. You’re right, when I followed your advice, all three histograms are similar.
I knew I had to be careful with binning and rounding off with ROOT, but I never had a case like this before.
Many thanks,

Machiel