Possible bug in TH1F::Fill?

Hi all,
I am experiencing a strange behaviour in TH1F::Fill: it seems that TH1F has a “saturation value” when filled via TH1F::Fill, while this does not apply if we use SetBinContent…

Here is a macro to explain my problem:

#include <TH1.h>
#include <TROOT.h>
#include <TClass.h>

#define MAX 1.7e7 /* slighly greater than 2**24 */
// #define MAX 2.2e9 /* slighly greater than 2**31, enought for TH1I */

void test_saturation(TH1 *h1)
{
  printf("---------------------------------------------------\n");

  // stupid fill, but 
  while(1)
    {
      h1->Fill(3.5);
  
      if(fabs(h1->GetBinContent(4)-h1->GetBinContent(3))<0.1) // Fill did non increment the bin
	break;

      if(h1->GetBinContent(4)> MAX )
	{
	  printf("Maximum bin count for %s: greater than %e ...\n",h1->IsA()->GetName(), h1->GetBinContent(4));
	  return;
	}

      h1->Fill(2.5);
      
    }
  printf("Maximum bin count for %s: %14.1f\n",h1->IsA()->GetName(), h1->GetBinContent(4));


  // let's try to put a "forbidden" value:
  printf("Checking max SetBinContent: ");
  double val= h1->GetBinContent(4)+10; // bigger value, that is "forbidden" with Fill()
  h1->SetBinContent(2,val);

  if( fabs(h1->GetBinContent(2)-val)<0.1) // we succeded!?
    printf(" ERROR: inconsistent SetBinContent and Fill!!!\n");
  else
    printf("OK.\n");
}

void test_saturation()
{
  printf("Testing with root %s and gcc: ",gROOT->GetVersion());
  fflush(stdout);
  system("gcc --version | head -n 1 | sed s/'.* '//g");
  printf("\n");

  TH1C *h1c=new TH1C("h1c","h1c",10,0,10);
  test_saturation(h1c);

  TH1S *h1s=new TH1S("h1s","h1s",10,0,10);
  test_saturation(h1s);

  TH1I *h1i=new TH1I("h1i","h1i",10,0,10);
  test_saturation(h1i);

  TH1F *h1f=new TH1F("h1f","h1f",10,0,10);
  test_saturation(h1f);

  TH1D *h1d=new TH1D("h1d","h1d",10,0,10);
  test_saturation(h1d);

}

Running it with

root test_saturation.C+

i get:

Testing with root 5.26/00 and gcc: 4.3.3

---------------------------------------------------
Maximum bin count for TH1C:          127.0
Checking max SetBinContent: OK.
---------------------------------------------------
Maximum bin count for TH1S:        32767.0
Checking max SetBinContent: OK.
---------------------------------------------------
Maximum bin count for TH1I: greater than 1.700000e+07 ...
---------------------------------------------------
Maximum bin count for TH1F:     16777216.0
Checking max SetBinContent:  ERROR: inconsistent SetBinContent and Fill!!!
---------------------------------------------------
Maximum bin count for TH1D: greater than 1.700000e+07 ...

same results on root 4.00/06 and gcc: 2.96 (yes I still have it around :slight_smile: ) and 5.22/00 and gcc: 4.3.2.

All histos type seems ok except for TH1F… Am i doing something wrong?
Regards!
Luigi

Hi,

you are using a TH1F which is based on floating point precision, which is the order of 10^-7.
You you are having bin content of the order of 10^7 and you want to look at difference at the level of 1 you should use the TH1 based on double precision (TH1D).
To know more about floating point precision, you can look at docs.sun.com/source/806-3568/ncg_goldberg.html

Best Regards

Lorenzo

Hi,
yes, the precision indeed is the float mantissa and this is ok.
The problem is that, if you run an analysis of the type:

while( loop on all the events )
{
    ...
    h1->Fill(.....)
}

you may face the problem: “TH1F has no maximum bin count, but the histogram saturates at 1<<24”. Should we add a warning in the TH1 documentation??

Morever: is TTree using TH1F for TTree::Draw ? a colleague of mine is facing exactly this problem when doing mytree->Draw(“myvar”) …

Regards!
Luigi

Hi,

yes, it is correct, TTree::Draw creates a TH1F and I think we should move to a TH1D. You (or your friend) should post this problem in Savannah
(savannah.cern.ch/bugs/?func=add … up=savroot)

In the documentation is already written that the maximum precision for a TH1F is seven digits.
(see root.cern.ch/root/htmldoc/TH1F.html )

Lorenzo

Done: savannah.cern.ch/bugs/?63873

already closed…