Confusing behavior of SetRangeUser() and fitting range


I got confused with the behavior of TAxis::SetRangeUser() and the fitting range in TH1::Fit(). From my observation, the fitting range is limited only to the selected user range, and a fit outside this range is not working, as this message claims:

Warning in ROOT::Fit::FillData: fit range is outside histogram range, no fit data for xaxis

This is an example macro:

    // histogram range is 0-1000e6
    dTSig_refitted->GetXaxis()->SetRangeUser(0, 500e3);
    auto f = new TF1("f", "expo(0)", 600e3, 600e6);
    dTSig_refitted->Fit(f, "", "", 600e3, 600e6);

If you remove the dTSig_refitted->GetXaxis()->SetRangeUser(0, 500e3); line, it would work and provide correct fit.

After checking with documentation:

  • TAxis::SetRangeUser ROOT: TAxis Class Reference says:

    Set the viewing range for the axis from ufirst to ulast (in user coordinates, that is, the “natural” axis coordinates).

  • Also TAxis::SetRange ROOT: TAxis Class Reference does not say anything about side effects for fitting.

  • But the TH1::Fit() documentations says:

    The default fitting of an histogram (when no option is given) is perfomed as following:

    • the full range of the histogram is used;

which contradicts observed behavior.

Could you please verify what is the proper behavior, and perhaps update the documentation?
In my opinion the histogram viewing range should not limit the fitting range. One has the TH1::Fit() fitting range to do this.


Hi Rafał,

I am adding in the loop @moneta in order to best follow up your enquiry.


Anything new about this?

If you read a bit below in the documentation, it says:

The fitting range is also limited by the histogram range defined using TAxis::SetRange or TAxis::SetRangeUser. Therefore the fitting range is the smallest range between the histogram one and the one defined by one of the two previous options described above.

I opened [skip-ci] clarify side effects of SetRange when fitting by ferdymercury · Pull Request #15096 · root-project/root · GitHub

I see that you updated the documentation. I was rather hoping on removing the side effect of TAxis::SetRange(User). There is already fit range determination by the TF1 function definition or parameters to TH1::Fit() and changing the view of the histograms (this is what SetRange does) really should not affect the fit. In my opinion the fix went in very wrong direction.

Breaking backward compatibility might be problematic. People are used to zoom and then fit using the GUI. If the fit silently uses the whole range, it might give wrong results and the user has no way to know.

If the devs agree that they want to change a longstanding behavior and break backward compatibility, I can change the PR.

The GUI (Fit Panel) is just an overlay. There is no problem to implement custom logic which reads the axis range and use it for fitting. The GUI also have a sliders to limit fit range and it is also on top of the view range. So there is definitely way to preserve old behavior of GUI.