Dividint 2 TGraphErrors

Hi all,

I am new at root, so i still need some help.
I wrote a script for fitting two Graphs. So now I have 2 TGRaphErros objects fitted, how can I divide these two fit functions to get a “ratio” between them?

Thank you all in advance.

Hi Michael,

this snippet does what you need:

TF1 f("f","sin(x)",0,10);
TF1 g("g","x",0,10);
TF1 h("h","f(x)/g(x)",0,10);
h.Draw();

What happens here is that the function f and g are constructed and registered in the list of functions known to ROOT. After that, the function h is constructed and in its formula the names “f” and “g” could be used.

Cheers,
Danilo

Hi, thank you for your reply.

However I am not sure if I did it correctly.

First of all I have declared function:

Double_t fitfunction(Double_t *x, Double_t *par)
{
return par[0]+par[1]/pow(x[0],par[2])+par[3]/pow(x[0],pow(2,par[4]));
}

Than in my code i have two functions like:

TF1 *f1 = new TF1("fitfunc",fitfunction,0,x1max,5);

and

TF1 *f2 = new TF1(“fitfunc”,fitfunction,0,x2max,5);

Than in the end I try:

TF1 h_of_x = new TF1(“h_of_x”,“f1(x)/f2(x0)”,0,60000,5);

And I get this:

Error in TF1::TF1: can not find any function at the address 0x15b7758. This function requested for h_of_x
Error: Can’t call TF1::TF1((class TF1*)0x166efc0) in current scope new_fit.C:224:
Possible candidates are…
(in TF1)
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(void);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,const char* formula,Double_t xmin=0,Double_t xmax=1);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,Double_t xmin,Double_t xmax,Int_t npar);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,void* fcn,Double_t xmin,Double_t xmax,Int_t npar);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,ROOT::Math::ParamFunctor f,Double_t xmin=0,Double_t xmax=1,Int_t npar=0);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,void* ptr,Double_t xmin,Double_t xmax,Int_t npar,const char* className);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,void* ptr,void*,Double_t xmin,Double_t xmax,Int_t npar,const char* className,const char* methodName=0);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const TF1& f1);
(in TFormula)
*** Interpreter error recovered ***

Do you know what am I supposed to do now?

Best,
Marek

Hi Marek,

inside the formula of the combined TF1 one should use the name of the TF1s and not the name of the variable which represent them. In your case:

TF1 *f1 = new TF1("fitfunc1",fitfunction,0,x1max,5);
TF1 *f2 = new TF1("fitfunc2",fitfunction,0,x2max,5);
TF1 h_of_x = new TF1("h_of_x","fitfunc1(x)/fitfunc2(x0)",0,60000,5);

Cheers,
Danilo

TF1 *f1 = new TF1(“fitfunc1”,fitfunction,0,x1max,5);

TF1 *f2 = new TF1(“fitfunc2”,fitfunction,0,x2max,5);

TF1 hox = new TF1(“h_of_x”,“fitfunc1(x)/fitfunc2(x)”,0,60000,1);

Gives me the output like:

Error in TF1::TF1: can not find any function at the address 0x1bbcef8. This function requested for hox
Error: Can’t call TF1::TF1((class TF1*)0x1bb9f40) in current scope new_fit.C:224:
Possible candidates are…
(in TF1)
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(void);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,const char* formula,Double_t xmin=0,Double_t xmax=1);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,Double_t xmin,Double_t xmax,Int_t npar);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,void* fcn,Double_t xmin,Double_t xmax,Int_t npar);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,ROOT::Math::ParamFunctor f,Double_t xmin=0,Double_t xmax=1,Int_t npar=0);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,void* ptr,Double_t xmin,Double_t xmax,Int_t npar,const char* className);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const char* name,void* ptr,void*,Double_t xmin,Double_t xmax,Int_t npar,const char* className,const char* methodName=0);
/usr/lib64/root/libHist.so -1:-1 0 public: TF1 TF1::TF1(const TF1& f1);
(in TFormula)
*** Interpreter error recovered ***

Best,
Marek

As far as I know, TF1 objects can reference other TF1 objects but this EXCLUDES all general C/C++ (CINT) interpreted and compiled functions (and basic polynomial functions polN).

Hi Marek,

I was maybe too quick answering. In ROOT6 it’s possible to achieve your goal:

void myMacro(){
gInterpreter->ProcessLine("auto fitfunction = [](Double_t *x, Double_t *par) { return par[0]+par[1]/pow(x[0],par[2])+par[3]/pow(x[0],pow(2,par[4]));}");
gInterpreter->ProcessLine("auto x1max = 12.;auto x2max=11.;");
auto f = (TF1*) gInterpreter->ProcessLine("TF1 fitfunc1(\"fitfunc1\",fitfunction,0,x1max,5);");
auto g = (TF1*) gInterpreter->ProcessLine("TF1 fitfunc2(\"fitfunc2\",fitfunction,0,x2max,5);");
TF1 h_of_x("h_of_x","fitfunc1(x)/fitfunc2(x)",0,10);
}

I understand that this is less than optimal from the point of view of interfaces, but we are working hard to make this easier.

Cheers,
Danilo

Hi again.

Thank you all for help.

I solved id in that way:

TF1 *f1 = new TF1 (…)
TF1 *f2 = new TF1 (…)
TF1 *hox = new TF1(“hox”,"([0]+[1]/pow(x,[2])+[3]/pow(x,pow(2,[4])))/([5]+[6]/pow(x,[7])+[8]/pow(x,pow(2,[9])))",0,100000);

hox->SetParameter(0,p0);
hox->SetParameter(1,p1);
hox->SetParameter(2,p2);
hox->SetParameter(3,p3);
hox->SetParameter(4,p4);
hox->SetParameter(5,d0);
hox->SetParameter(6,d1);
hox->SetParameter(7,d2);
hox->SetParameter(8,d3);
hox->SetParameter(9,d4);

previously I stored p[x] & d[x] in arrays.

Is it ok?

Best, Marek

It looks like a good solution. Thanks for publishing this.