TH1::Divide() + TH1::Scale() doubles # of bins


I noticed this strange (to me) behaviour. I wonder whether it’s a bug or something I’m not understanding,

I declare 3 TH1 with identical # of bins and range. I fill the first two and then call TH1::Divide() on the 3rd to put into it the divison bin by bin of the first 2.
Everything fine.
Then I want to normalize it and call TH1::Scale().
After this operation the # of bins is double and the range extented to twice the previous value (in other words the bin size is unchanged).
Of course if I scale the orignal 2 histos the issue is not there, I observe it only on histos which I fill with Divide().

I find it pretty peculiar but maybe there’s something I’m not understanding
Thank you

Could you post the shortest possible running script featuring this problem?


Dear Rene’,

thanks for your answer.
ok, I investigated a little further and I have to say it’s not related to the use of TH1::Divide() but of TAxis::SetTimeDisplay();
this code should clarify what I mean.

TTimeStamp start(2007, 12, 15, 0, 0, 0);
TTimeStamp stop(2009, 8, 22, 0, 0, 0);
TTimeStamp offset(2000, 1, 1, 0, 0, 0);
ULong_t start_time = start.GetSec()-offset.GetSec();
Int_t start_day = start_time/3600/24;
ULong_t stop_time = stop.GetSec()-offset.GetSec();
Int_t stop_day = stop_time/3600/24;
Int_t nbins = stop_day-start_day;
TH1F *hlt_vs_day = new TH1F(“hlt_vs_day” , “Live Time vs day” , nbins , start_time, stop_time);
hlt_vs_day ->GetXaxis()->SetTimeDisplay(1);
cout << hlt_vs_day->GetNbinsX() << endl;
cout << hlt_vs_day->GetNbinsX() << endl;

If you comment the SetTimeDisplay you can see that the call to Scale() doesn’t affect nbins any longer.

Thank you


Move the call to SetTimeDisplay after the call to Divide.
Otherwise you are hitting a very special case when setting the content
of the very last bin.


thank you, it works.
though I don’t understand how a TAxis call can change the TH1, I though TAxis is only related to how the TH1 is displayed…
Anyhow, thank you

TAxis::SetTimeDisplay does not change itself the number of bins. This function indicates that the axis will be in time units. Later on (eg when calling TH1::Divide or any other function setting the bin contents) when the last bin is touched and it turns out that the end of the bin is above the latest nice time value, the system will automatically double the number of bins such that the last value is nicely within the time range. Of course, in your example, this should not happen, it is a matter of optimisation of many tiny cases like this example that makes our life (and yours too ::slight_smile: more difficult.


there is one thing that would make everybody’s life much easier:
if every support service was so fast and effective like root’s one!
thank again