Problem fitting a function in one range, and plotting in a different range

Hi,

I have a 1-d histogram that I wish to fit with a function (TF1). The histogram runs from 500 MeV/c^2 to 2.2 GeV^2. I would like to fit the function in a limited range of the data (and get the parameters and chi^2 for that range), but then draw the function over the entire range of the histogram, to visually see the extrapolation. I can restrict the fit range with “R”, but then I have not figured out how to draw it over the entire histogram range. I also tried cloning or copying the function, figuring I could then extend the range, but couldn’t get that to work either.

What is the easiest way to do this?

Spencer Klein
LBNL

Try this: fit first the function without drawing. (Option 0 or sth like that).
Then call f->SetRange(min,max); f->Draw("same");

Doh - thank you very much.

Now I’m having a different problem. I want to expand my fitting function from 11 to 14 fitting parameters:

TF1 *func = new TF1(“func”,fitfBW1,0.6,2.2,14);
func->SetParameters(0.767,0.151,700.,-500.,1.E5, 1E5,24.,0.782,0.1,1.2 ,0.,1650.,130.,1.);

The TF1 seems to define OK, but whenever I try to use the function, I get error messages like

Users/sklein/STARstuff/twoprong/./dipionBW1.C:153:7: error: no matching member
function for call to 'SetParameters’
func->SetParameters(0.767,0.151,700.,-500.,1.E5,-1E5,24.,0.782,0.1,1.2,0…
^~~~~~~
/opt/local/libexec/root6/include/root/TF1.h:443:21: note: candidate function not
viable: requires at most 11 arguments, but 14 were provided
virtual void SetParameters(Double_t p0,Double_t p1,Double_t p2=0,…

with a similar error for

func->SetParNames("…

Am I missing something, or is this a fundamental limitation of ROOT? I am aware how difficult it is to fit to a function with 14 parameters, but it is easier for me to fix, if needed some parameters with func->FixParameter(10,0.), rather than having to hard-code masses, etc. into my fit function. I could not find documentation on the maximum number of parameters in a TF1; if this exists, it would be nice to document it.

Thanks for your help.

Spencer Klein

Yes, there is a limitation for just 11 parameters if given as function arguments. Try instead to pass the arguments as an array:

Double_t pars[14] = {0.767,0.151,700.,-500.,1.E5, 1E5,24.,0.782,0.1,1.2 ,0.,1650.,130.,1.}; func->SetParameters(pars);

Thanks! It would be nice to update the documentation to note the limitation on the number of parameters. Also, I was unable to get the argument-as-array approach to work for SetParNames, but can set each name individually with SetParName.

One more fit question: I have a fairly complicated TH1F which includes bins with different widths, read in from a file. I want to fit this function, and then histogram the residuals by subtracting the fit function from the input histogram. This seems, in principle fairly straightforward:

TH1F resid = (TH1F)massalldiff->Clone(“resid”);

for (int j=1;j<numbins;j++) {
double midbin=resid->GetBinCenter(j);
double differ = massalldiff->GetBinContent(j) - func->Eval(midbin);
resid->SetBinContent(j,differ);
}
resid->Draw();

Here massalldiff is the histogram, and func is the function.

and I am pretty sure that something like this worked in ROOT 5. However, I cannot get it to work properly in ROOT6.06, because when I clone the histogram, it also brings along the fit function; when I draw the resid, in addition to the residuals, I also get the fit function, which I both don’t want, and which messes up the scale. I tried 'resid->Draw(“0”), but that didn’t work, and I also tried cloning the histogram before the fit, but that didn’t work either. I would very much rather not have to create the new histogram by copying the new bin widths, etc. element by element from the old histogram. Any ideas?

Spencer

Well, here it is more or less obvious:
root.cern.ch/doc/master/classTF … 29c59c9828

Yes, consistency/coherence is not a strength of the ROOT interfaces… :wink:
You could suggest the developers to implement for ROOT6 the function SetParNames(array of names).

[quote=“spencer”]I would very much rather not have to create the new histogram by copying the new bin widths, etc. element by element from the old histogram. Any ideas?
[/quote]
Option a)

resid->GetListOfFunctions()->Clear();
resid->Draw();

Option b)

massaldiff->Fit(func,"N0");
TH1F *resid = (TH1F*)massalldiff->Clone("resid");
resid->Draw();

See:
root.cern.ch/root/html532/TH1.html#TH1:Fit