How to use self defined functions in fitting sub-ranges?

Hi,

I have a problem how to use a self defined functions while fitting some subranges of a histogram.

I followed the example in:
root.cern.ch/root/html/examples/multifit.C.html
and want now to change a predefined function (i.e. gaus/polX) into an own!?

In my macro I first define my function “PeakFit” and want to call it my main part - but always root says something like: "Bad numerical expression : “PeakFit”"
My code looks like:


Double_t PeakFit(Double_t *x, Double_t *par) {
  ...//MyFunction with  5 parameters
}

void MyFit(){
  Double_t par[11];
   g1    = new TF1("g1","pol2",-0.3,-0.1);
   g2    = new TF1("g2","pol2",0.1,0.3);
   signal = new TF1("signal","PeakFit",-0.1,0.1);
   TF1* fitFcn = new TF1("fitFcn","PeakFit+g1+g2",-0.3,0.3,11);
   Histo2fit_DeltaE->Fit("g1","ERL");
   Histo2fit_DeltaE->Fit("g2","ERL+");
   Histo2fit_DeltaE->Fit("signal","ERL+");
   g1->GetParameters(&par[0]);
   g2->GetParameters(&par[3]);
   signal->GetParameters(&par[6]);
   fitFcn->SetParameters(par);  
   Histo2fit_DeltaE->Fit("fitFcn","ERL+");
   Histo2fit_DeltaE->Draw();

...
}

Many thanks in advance,
Thomas

See example in tutorial FittingDemo.C

Rene

Hi,

I already used this example for defining my own functions but I could not manage to combine:

FittingDemo.C - self-defined functions fitted over the whole range and
multifit.C - pre defined functions fitted in single sub-ranges

into a macro fitting self-defined functions in sub-ranges.
I defined a function as in FittingDemo.C and tried to use it according to multifit.C instead of the pre-defined gaussian.

Apparently I cannot simply replace in TF1(const char* name, const char* formula, Double_t xmin = 0, Double_t xmax = 1) the formula character (i.e. “gaus”) by an own functions, which leads to a “Bad numerical expression” error.

Cheers,
Thomas

Did you look carefully to FittingDemo.C ?
In particular note the different TF1 constructors for simple functions
where the function is given by name (“name”)
and the others where you give a function pointer (without the “”) and
tha additional argument giving the number of parameters.

If you still have problems, please send the shortest possible script
that we can execute.

Rene

I am slowly approaching a solution to my problem :wink:
The remaining stumbling block is how to add g1, g2 & signal within fitFcn.

Many Thanks,
Thomas

Double_t HgFit(Double_t *x, Double_t *par) 
{
  return par[0]+par[1] *x[0]+par[2]*x[0]*x[0] ;
}
Double_t PeakFit(Double_t *x, Double_t *par) 
{
return 
  ( 
   (0.006*par[0]/sqrt(2*TMath::Pi())/par[2] * TMath::Exp(-0.5 * ( ((x[0]-par[1])/TMath::Max(1.e-10,par[2])) * ((x[0]-par[1])/TMath::Max(1.e-10,par[2])))))
   + 
   (0.006*par[3]/sqrt(2*TMath::Pi())/TMath::Max(1.e-10,par[4]) * TMath::Exp(-0.5 * ( ((x[0]-par[1])/TMath::Max(1.e-10,par[4])) * ((x[0]-par[1])/TMath::Max(1.e-10,par[4])))))
   );
}

void MyFit()
  {
  TH1D* Histo2fit=(TH1D*) MyHisto->Clone(); 
   Double_t par[11];

   g1    = new TF1("g1",HgFit,-1,-0.5,3);
   g2    = new TF1("g2",HgFit,0.5,1,3);
   signal = new TF1("signal",PeakFit,-0.5,0.5,5);
   TF1* fitFcn = new TF1("fitFcn",g1+g2+signal,-1,1,11);    // <-- how to add?

   Histo2fit->Fit("g1","ERL");
   Histo2fit->Fit("g2","ERL+");

   signal->SetParameter(0,1000);
   signal->SetParameter(1,-0.01);
   signal->SetParameter(2,0.1);  
   signal->SetParameter(5,0.01);
   Histo2fit->Fit("signal","ERL+");

   g1->GetParameters(&par[0]);
   g2->GetParameters(&par[3]);
   signal->GetParameters(&par[6]);

   fitFcn->SetParameters(par);  
   Histo2fit->Fit("fitFcn","ERL+");
   Histo2fit->Draw();

   g1->SetLineColor(7);
   g2->SetLineColor(8);
   signal->SetLineColor(9);
   fitFcn->SetLineColor(8);
   g1->Draw("same");
   g2->Draw("same");
   signal->Draw("same");
}

I can only repeat my previous post ::slight_smile:
Look carefully at example FittingDemo.C where the fitFunction
is the sum of two other functions

Rene