Query for fitting

Dear All

I was trying to fit the camel function using root. Please see the attached plot. I am making a,b,c as variables but still, I am not able to fit it properly. Please see the attached root program and suggest if I can improve this program or not ?

Expression for camel fitting function is

a*exp(-by^2)Cosh(cy)

Thnaks
Sarvesh

Welcome to the ROOT forum.

You didn’t attach the plot nor the ROOT program.

This message is coming while uploading files

An error occurred: Sorry, new users can’t put links in posts.

You can inline the code.

void plot_fit()
{
TGraph *gr = new TGraph("Book1.txt","%lg %lg");
gr->SetTitle("Gaussian function fitting");
gStyle->SetTitleFontSize(0.06);

gr->GetXaxis()->SetTitle("Rapidity distribution (in keV)");
gr->GetXaxis()->CenterTitle(true);
gr->GetXaxis()->SetLabelSize(0.04);
gr->GetXaxis()->SetLabelFont(22);
gr->GetXaxis()->SetTitleSize(0.05);
gr->GetXaxis()->SetTitleFont(22);

gr->GetYaxis()->SetTitle("Counts");
gr->GetYaxis()->CenterTitle(true);
gr->GetYaxis()->SetLabelSize(0.04);
gr->GetYaxis()->SetLabelFont(22);
gr->GetYaxis()->SetTitleSize(0.05);
gr->GetYaxis()->SetTitleFont(22);

//Marker Styles
gr->SetMarkerStyle(kFullDotLarge);
gr->SetMarkerSize(0.7);
gr->SetMarkerColor(kBlue);

//Line Styles
gr->SetLineWidth(2);
gr->SetLineColor(kBlack);

//In-built root function
TF1 *f = new TF1 ("custom_fit","[0]*exp(-[1]*x*x)*cosh([2]*x)",-5,5);

f->SetParameter(0, 0.34);
f->SetParameter(1, 0.78);
f->SetParameter(2, 1.76);



// Perform the fit
gr->Fit("custom_fit", "R");

// Access and print the fit results
double A = f->GetParameter(0);
double B = f->GetParameter(1);
double C = f->GetParameter(2);

// Print the parameter values to the console
cout << "Fit Results:" << endl;
cout << "A: " << A << endl;
cout << "B: " << B << endl;
cout << "C: " << C << endl;



// Perform the fit
//graph->Fit("custom_fit", "R");

// Access and print the fit results
double fitted_A = f->GetParameter(0);
double fitted_B = f->GetParameter(1);
double fitted_C = f->GetParameter(2);

// Access the fitting equation from the fit function's title
const char* fitting_equation = f->GetTitle();

// Extract the equation portion of the title
std::string equationStr(fitting_equation);

// Find the position of the colon character in the equation string
size_t colonPos = equationStr.find(':');

// Check if the colon character was found
if (colonPos != std::string::npos) {
    // Extract and print only the equation part
    std::string equation = equationStr.substr(0, colonPos);
    cout << "f=[A]*exp(-[B]*x*x)*cosh([C]*x): " << equation << endl;
} else {
    // If colon character is not found, print the entire title
    cout << "f=[A]*exp(-[B]*x*x)*cosh([C]*x): " << fitting_equation << endl;
}

// Print the parameter values
cout << "A: " << fitted_A << endl;
cout << "B: " << fitted_B << endl;
cout << "C: " << fitted_C << endl;


TCanvas *c1 = new TCanvas("c1", "Fit Canvas");

#include "TGraph.h"
#include "TF1.h"






//graph->Draw("AP"); // "AP" option for data points with error bars
f->Draw("same");
c1->Update();


//User defined function 

f->SetParameters(10,0.5);
f->SetLineColor(kRed);
f->SetLineStyle(1);
f->SetLineWidth(4);


//Fitting Graph with function
gr->Fit("f");
gr->Draw("AP");



//Legends
TLegend *leg = new TLegend(.65,.65,.85,.80);
leg->SetBorderSize(1);
//leg->SetFillColor(kGreen);
leg->AddEntry(gr,"Exp. Points");
leg->AddEntry(f,"fit");
leg->Draw("same");

//Printing parameters values (Not required for in-built functions)
//double *par = f->GetParameters();
//cout<<"p0="<<par[0]<<"\t"<<"p1="<<par[1]<<"\n";
}

Data file is big, not able to copy paster here as it exceeds the number of characters. It allows only 32000 but data file has 38425 characters.

Email me the data file and I will post it for you.

Yes done the email… pls check

Thanks
Sarvesh

void plot_fit()
{
   auto gr = new TGraph("Book1.txt","%lg %lg");
   gr->SetTitle("Gaussian function fitting");

   gStyle->SetTitleFontSize(0.06);

   gr->GetXaxis()->SetTitle("Rapidity distribution (in keV)");
   gr->GetXaxis()->CenterTitle(true);
   gr->GetXaxis()->SetLabelSize(0.04);
   gr->GetXaxis()->SetLabelFont(22);
   gr->GetXaxis()->SetTitleSize(0.05);
   gr->GetXaxis()->SetTitleFont(22);

   gr->GetYaxis()->SetTitle("Counts");
   gr->GetYaxis()->CenterTitle(true);
   gr->GetYaxis()->SetLabelSize(0.04);
   gr->GetYaxis()->SetLabelFont(22);
   gr->GetYaxis()->SetTitleSize(0.05);
   gr->GetYaxis()->SetTitleFont(22);

   //Marker Styles
   gr->SetMarkerStyle(kFullDotLarge);
   gr->SetMarkerSize(0.7);
   gr->SetMarkerColor(kBlue);

   //Line Styles
   gr->SetLineWidth(2);
   gr->SetLineColor(kBlack);

   //In-built root function
   auto f = new TF1 ("f","[0]*exp(-[1]*x*x)*cosh([2]*x)",-3,3);
   f->SetLineColor(kRed);
   f->SetLineStyle(1);
   f->SetLineWidth(4);
   f->SetParameter(0, 50.);
   f->SetParameter(1, 1.);
   f->SetParameter(2, 2.);

   // Perform the fit
   gr->Fit("f");

   // Draw the fit and data
   gr->Draw("APL");

   //Draw the legend
   TLegend *leg = new TLegend(.65,.65,.85,.80);
   leg->SetBorderSize(1);
   leg->AddEntry(gr,"Exp. Points");
   leg->AddEntry(f,"fit");
   leg->Draw();
}

Book1.txt (22.9 KB)

Thanks Olivier, Can we go more close in fitting exactly it. Or this is the best fit by the camel function.

Regards
Sarvesh

I am not sure which function is the best or if , by adjusting the initial values of the parameter, this function can do better. Let’s ask @moneta, he will know better.

Dear Couet

Waiting for your reply on best fit…

Thanks
Sarvesh

Hello,

I think we can argue here on what is the best function which can reproduce the trend you measured, however the person who is best placed to do so is you.
You know your experimental setup, you know the phenomenon you are measuring and know the model/theory that describes it best: I am sure you can identify the best fucntion - any suggestion we may make risks to be unphysical and spoil the meaning of the physics you are studying!

I hope this helps.

Best,
D

1 Like

Thanks for Physics reply, yes its a bit difficult to justify in physics slight deviation from camel function…But I shall try to hunt for it. Still Can’t we force the Camel function to fit the graph more better by increasing accuracy or modifying the algorithm of fit?

Regards
Sarvesh

Dear Sarvesh,

what I propose is to check by eye if you can find the right combination of parameters values that reproduce your trend. That will tell you if the functional form is the right one. Right?
I hope this helps.

Cheers,
Danilo

ROOT provides a GUI (allowing to set the parameters of a function interactively) which might be of some help for that. See the following picture:

  1. Execute the 4 commands shown in the terminal
  2. In the canvas View->Editor
  3. Click on the function (the horizontal red line)
  4. Check “Update”
  5. Click on the “Set parameters…” button

Thanks Couet, that will be very helpful to do matching…

Do not expect too much of it. I tried a bit and I must admit it was not easy to get an exact match. In other words, the ROOT fitter does a good job already.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.