Write Method Seems to Changes TF1 Function or Parameters

Hi rooters,

I have a problem with saving a TF1 to a file- the saved function seems to produce different values when evaluated compared to in-scope. I would be grateful for any pointers to resolve the issue.

Thank you,
Martin


double d_funct( double *x, double *par )
{
double E = x[0];

double C = par[0]; // normalization
double gamma_a = par[1]; // low x power law slope
double gamma_b = par[2]; // high x power law slope
double E_0 = par[3]; // transition point parameter between power laws

if ( E < (gamma_a-gamma_b) * E_0 ) return C * pow(E, gamma_a) * exp(-E/E_0);
else return C * pow(E, gamma_b) * pow( (gamma_a-gamma_b)*E_0, gamma_a-gamma_b) * exp(gamma_b-gamma_a);

}

void functsavetest()
{

TFile *f_out = new TFile("./functsavetest_output.root",“recreate”);
TF1 *f1_testfunct = new TF1(“f1_testfunct”, d_funct, 0.1, 1e+04, 4);
f1_testfunct->SetParameters( 700, -4, -4, 60 );
cout << "Function evaluated at x= 10: f(x) = " << f1_testfunct->Eval(10) << endl;
f_out->cd();
f1_testfunct->Write(“f1_testfunct”);
f_out->Close();

}


// command line:

$ root -l -b -q functsavetest.C
root [0]
Processing functsavetest.C…
Function evaluated at x= 10: f(x) = 0.07
$ root -l functsavetest_output.root
root [0]
Attaching file functsavetest_output.root as _file0…
(TFile *) 0x2610e20
root [1] TF1 f1_readback = (TF1)_file0->Get(“f1_testfunct”);
root [2] f1_readback->Eval(10)
(Double_t) 6.30699e+06
root [3]

Sorry, forgot to add that I am using ROOT 6.08/06, and that I find similar issues when plotting the saved function in a TBrowser- the functional shape is changed. Maybe the double definition is somehow not entirely saved with the function, or there is a precision limitation- any suggestions are appreciated.

Search for “WARNING! A function created with this constructor cannot be Cloned.” (which also means that you cannot “save” them) in the TF1 class description.

Hi Wile_E_Coyote,

Thank you for your reply. I seem to have had success previously (in older versions of ROOT) with saving TF1 defined through double functions to files and reading them back correctly- the above post reflects the first time that I encountered issues in doing that. I doubt that the handling of such functions changed over time, so I am at a loss of explanation…
Is there any way to plot a TF1 that is defined via a double function on a canvas and save the canvas to a file without the TF1 being corrupted?

Thank you,
Martin

Hi Martin,

Wile has a point. ROOT is able to serialise (therefore write, for example) basically any data type. Functions are special though. In memory they do not have any layout, like for example classes and structs, they are just a pointer to executable memory. It is not possible to serialise such data as at the end of the day, concretely, we are talking about machine instructions.

Cheers,
D

Hi Dpiparo,

Thank you for your comment. Is there any way around the serialization issue to obtain a plot of a double function-defined TF1 in a canvas that can be saved to a file and read back without corrupting the graphic representation?

When drawing the function into a canvas in an interactive session, the function is displayed fine. However after saving the canvas to a file, the function has changed shape when reloading it from the file. Is there a way to capture the graphic representation of a function and detach it from the executable memory portion? Maybe previous versions of ROOT automatically invoked the ::Paint() method to create a histogram that was used to save the graphical representation of a TF1 to file. With the ROOT version I use, I cannot seem to call the ::Paint() method to create the histogram. I would be very grateful for any solution tips.

Thank you,
Martin

I ended up storing evaluations of the TF1 I am trying to store the graphics of in a TGraph on a binning and plot the TGraph instead of the TF1. It is somewhat surprising that no other users seem to have a need to store graphic representations of function-defined TF1 objects in a file for future reference since this functionality does not seem to be implemented in ROOT.

Thank you for your help,
Martin

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