Cloning vs. Copying TF1

I learned that cloning TF1 is not a trivial issue, and there is more variations which are not clonable than clonable. But I did not found any mechanism allowing to determine, whether the object of TF1 which is passed e.g. to other function can be actually cloned. What is the best way to determinate it? I found that GetexpFormula() should return empty string if can’t be cloned.

But anyway, I also found that actually calling Copy can give me a copy of original function. Here is some demo I created to test it.

[code]double test_func(double * x, double * pars)
{
double _x = x[0];
return pars[0] + pars[1] * _x + pars[2] * _x * _x;
}

void tf1_clone_demo()
{
double pars[3] = { 1, 0, 3 };
TF1 * f1 = new TF1(“f1”, “[0] + [1]*x + [2]xx”, -5, 5);
f1->SetParameters(pars);

TF2 * f2 = f1->Clone();
f2->SetParameter(0, 5);
f2->SetLineStyle(2);

f1->Draw();
f2->Draw("same");

cout << " f1 = >>" << f1->GetExpFormula() << "<<"  << endl;
cout << " f2 = >>" << f2->GetExpFormula() << "<<"  << endl;

if (f1->GetExpFormula().IsNull())
	cout << "f1 can't be cloned" << endl;

if (f2->GetExpFormula().IsNull())
	cout << "f2 can't be cloned" << endl;

TF1 * f3 = new TF1("f3", test_func, -5, 5, 3);
f3->SetParameters(pars);
f3->SetParameter(0, 10);
f3->SetLineStyle(3);
f3->SetLineColor(3);

f3->Draw("same");
cout << " f3 = >>" << f3->GetExpFormula() << "<<" << endl;

if (f3->GetExpFormula().IsNull())
	cout << "f3 can't be cloned" << endl;

TF1 * f4 = f3->Clone();
f4->SetParameters(pars);
f4->SetParameter(0, 15);
f4->SetLineStyle(4);
f4->SetLineColor(4);

f4->Draw("same");
cout << " f4 = >>" << f4->GetExpFormula() << "<<" << endl;

if (f4->GetExpFormula().IsNull())
	cout << "f4 can't be cloned" << endl;

TF1 * f5 = new TF1();
f3->Copy(*f5);
f5->SetParameters(pars);
f5->SetParameter(0, 20);
f5->SetLineStyle(5);
f5->SetLineColor(5);

f5->Draw("same");
cout << " f5 = >>" << f5->GetExpFormula() << "<<" << endl;

if (f5->GetExpFormula().IsNull())
	cout << "f5 can't be cloned" << endl;

TF1 * f6 = new TF1();
f1->Copy(*f6);
f6->SetParameters(pars);
f6->SetParameter(0, 25);
f6->SetLineStyle(6);
f6->SetLineColor(6);

f6->Draw("same");
cout << " f6 = >>" << f6->GetExpFormula() << "<<" << endl;

if (f6->GetExpFormula().IsNull())
	cout << "f6 can't be cloned" << endl;

}[/code]

and here is the output[quote]
root [0]
Processing tf1_clone_demo.C…
Info in TCanvas::MakeDefCanvas: created default TCanvas with name c1
f1 = >>([0]+([1]x))+([2](xx))<<
f2 = >>([0]+([1]x))+([2](x
x))<<
f3 = >><<
f3 can’t be cloned
f4 = >><<
f4 can’t be cloned
f5 = >><<
f5 can’t be cloned
f6 = >>([0]+([1]x))+([2](x*x))<<[/quote]

Can anyone tell me whether it is good approach or there are some things that can be done better?

If you are using ROOT 5, search the TF1 class description for a “WARNING! A function created with this constructor cannot be Cloned.”.

HI,

TF1 based on TFormula expressions (i.e functions defined as a string) , which are the cases 1,2,3 of
root.cern.ch/doc/master/classTF1.html

can be cloned and saved in a file. TF1::Clone is based on Object::Clone which uses the ROOT I/O system to copy the object.

Instead TF1 based on real C/C++ functions (e.g. lambda or functors), cases 4,5,6 cannot be cloned and saved in a file, because they depend on some functional code.
It is instead possible to copy them using the copy constructor or TF1::Copy, but this will work as far the function code on which they are based is still available and valid.

Lorenzo

Thank you for replies. I found in the doc already which ctors can be clone and which not, and that I can copy them. But my question (maybe wasn’t clear enough) is, whether there is any official, the best way, to determine whether function can be cloned or not? I check it by checking length of the string returned by GetExpFormula(). Maybe in the future version you can add public function IsClonable() or smth like this?

I need it, because I have fitting code, which does some manipulations on the function parameters. Therefore for me is the best to clone function, or copy it, whether which of the options is available.