Problem with cloning and fitting TGraph

I was reading TGraph from problem.root with problem.C, clone the graph and fit them.
the problem is that, whenever i perform a Fit, the TGraph that were written to the output file is not accessible (i opened it with the following code and it keep restarting the kernel), but it is OK when i did not perform a fit (it is not possible !!! i want them to be fitted !!!)

fname = "fitted_problem.root"
file = r.TFile(fname)
file.ls()

c = r.TCanvas("c","c",1200,600)
gr = file.Get("gr_x_1667176620.642.78")
gr.SetMarkerStyle(7)
gr.Draw("AP")
c.Draw()

ROOT Version: 6.24.00 (conda)
Platform: centos7
Compiler: gcc9


problem.root (1.5 MB)
problem.C (2.3 KB)

I made this macro:

void read_problem(){
   auto f = new TFile("fitted_problem.root");
   f->ls();

   TGraph *gr = (TGraph *)f->Get("gr_x_1667176620.642.78");
   gr->Draw("AP");
}

It gives me:

% .x read_problem.C
root [0] 
Processing read_problem.C...
TFile**		fitted_problem.root	
 TFile*		fitted_problem.root	
  KEY: TGraph	gr_x_1667176620.642.78;5	x vs time (muonID:1667176620.642.78); time [#mus]; x [mm] [current cycle]
  KEY: TGraph	gr_x_1667176620.642.78;4	x vs time (muonID:1667176620.642.78); time [#mus]; x [mm] [backup cycle]
  KEY: TGraph	gr_x_1667176620.642.78;3	x vs time (muonID:1667176620.642.78); time [#mus]; x [mm] [backup cycle]
  KEY: TGraph	gr_x_1667176620.642.78;2	x vs time (muonID:1667176620.642.78); time [#mus]; x [mm] [backup cycle]
  KEY: TGraph	gr_x_1667176620.642.78;1	x vs time (muonID:1667176620.642.78); time [#mus]; x [mm] [backup cycle]
  KEY: TTree	tree;1	a tree
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
input_line_37:2:187: error: expected expression
Double_t TFormula____id15367673592536998465(Double_t *x,Double_t *p){ return p[0]+(p[1]+p[2]*x[0]+p[3]*x[0]*x[0])*TMath::Cos(p[4]*x[0]+p[5])+(p[6]+p[7]*x[0]+p[8]*x[0]*x[0])*TMath::Cos({[#omega_x[0]]}*x[0]+{[#phi_x[0]]}) ; }
                                                                                                                                                                                          ^
input_line_38:2:187: error: expected expression
Double_t TFormula____id15367673592536998465(Double_t *x,Double_t *p){ return p[0]+(p[1]+p[2]*x[0]+p[3]*x[0]*x[0])*TMath::Cos(p[4]*x[0]+p[5])+(p[6]+p[7]*x[0]+p[8]*x[0]*x[0])*TMath::Cos({[#omega_x[0]]}*x[0]+{[#phi_x[0]]}) ; }
                                                                                                                                                                                          ^
Error in <prepareMethod>: Can't compile function TFormula____id15367673592536998465 prototype with arguments Double_t*,Double_t*
Error in <TFormula::InputFormulaIntoCling>: Error compiling formula expression in Cling
Error in <TFormula::DoEval>: Formula has error and  it is not properly initialized 

 *** Break *** segmentation violation
[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)
[/usr/lib/system/libsystem_c.dylib] __sF (no debug info)
[/Users/couet/git/couet-root-bin/lib/libHist.so] TF1::DoCreateHistogram(double, double, bool) (no debug info)
[/Users/couet/git/couet-root-bin/lib/libHist.so] TF1::Paint(char const*) (no debug info)
[/Users/couet/git/couet-root-bin/lib/libHistPainter.so] TGraphPainter::PaintGraphSimple(TGraph*, char const*) (no debug info)
[/Users/couet/git/couet-root-bin/lib/libHistPainter.so] TGraphPainter::PaintHelper(TGraph*, char const*) (no debug info)
[/Users/couet/git/couet-root-bin/lib/libGpad.so] TPad::PaintModified() (no debug info)
[/Users/couet/git/couet-root-bin/lib/libGpad.so] TCanvas::Update() (no debug info)
[/Users/couet/git/couet-root-bin/lib/libCling.so] TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) (no debug info)
[/Users/couet/git/couet-root-bin/lib/libCling.so] TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) (no debug info)
[/Users/couet/git/couet-root-bin/lib/libRint.so] TRint::Run(bool) (no debug info)
[/Users/couet/git/couet-root-bin/bin/root.exe] main (no debug info)
[/usr/lib/dyld] start (no debug info)
Root > 

ok. i change that line to :
TF1* fit_func = new TF1(Form("fit_func_%s",muonID), "[0] + ([1]+[2]*x + [3]*x*x ) * TMath::Cos([4]*x + [5]) + ([6]+[7]*x + [8]*x*x ) * TMath::Cos([9]*x + [10])",ta, tb);
and it still did not worked …

but after that, i found that the problem arose in the SetParName line… i simply cannot set the names of 11 parameters at the same time … (if i remember it correctly, this function only allows us to set up to 10, but can >10 if the function is compiled from a c++ function)

ps: i was doing in python version, thinking that the same applies when i comes to c++ …

I guess @moneta can help.

now it is clear that the SetParNames that gave the problem, and i dont have idea on WHY it gave problem in this particular use case (sorry I am still too young after using ROOT for 3 years !!!)

the temporary workaround would be :

		fit_func->SetParNames("xe","A","A1","A2","wc","pc","B","B1","B2");
		fit_func->SetParName(9,"wx");
		fit_func->SetParName(10,"px");

to have minimum version of human readable par names…

Hi,

The problem is in using the parameter names #omega_{x} and #phi_{x}# as parameter name. x is a special character of TFormula, used to identify the variable and you cannot use then as {x}. if you would just use #omega_x it will work fine. We can probably improve the TFormula parsing for this, but there is also this easy workaround.

Lorenzo

I just found that the problem can be avoided, if we define TF1 by a compiled c++ function, using
TF1("func_name", some_double_cpp_func, a, b , nvars);

Yes, if you defined the TF1 using a C++ function pointer or a functor, this problem is avoided. However, note that when cloning the function or when writing to disk, you will not be able to save the full function formula, but only the function values. This means that you will not be able to use for fitting teh TF1 object after cloning or reading from a file.

Lorenzo

1 Like

i am aware of this …

so if i use the cloned function to do fitting, i will end up with unexpected behavior am i right ?
also, can you elaborate more on what you meant by “only the function values” ?

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

Hi,
If you TF1 is created using a C++ function, (not as a string representing t he formula), when you clone or save the function to disk, only the vector of the function values evaluated in a grid will be saved. You can then plot the function afterwards, but not anymore change its parameters.
In this case you would need to re-create a new TF1 object with the corresponding C++ function.