Using TF1 functions


ROOT Version: 6.08/02
Platform: Linux CentOS 7
Compiler: Root macro


In a ROOT macro I am defining a TF1 function to be used in histogram fitting. The function depends on some variables defined in the main program.

After looking to the documentation and to some examples, I came up with the following code:

  auto fTemplateFunction = new TF1("tempfunc",[&](double* x, double* p){
      Double_t xx = x[0]-fTemplateCFShift;
      if (xx < 0.) return 0.;
      Double_t xint, xdec;
      xdec = std::modf(xx,&xint);
      Int_t xi = (Int_t)xint;
      printf("%f %f %f %f %d %f %f\n",p[0],x[0],fTemplateCFShift,xx,xi,xdec,p[0]*(fTemplate[xi]+(fTemplate[xi+1]-fTemplate[xi])*xdec));
      return p[0]*(fTemplate[xi]+(fTemplate[xi+1]-fTemplate[xi])*xdec);
    },0.,1024.,1);

I understood that the [&] definition allows the function to access variables from the main program, in this case fTemplateCFShift and fTemplate.

When I use this function to fit an histogram, I can see that the external variables are indeed correctly accessed:

h->Fit("tempfunc","","",200.,994.);
37128.852670 200.500000 177.458362 23.041638 23 0.041638 153.575151
37128.852670 201.500000 177.458362 24.041638 24 0.041638 157.093462
37128.852670 202.500000 177.458362 25.041638 25 0.041638 160.193099
etc.etc.

but if I try to use the function->Draw() command, the external variables are all zero:

fTemplateFunction->Draw();
37129.474010 200.500000 0.000000 200.500000 200 0.500000 0.000000
37129.474010 201.500000 0.000000 201.500000 201 0.500000 0.000000
37129.474010 202.500000 0.000000 202.500000 202 0.500000 0.000000
etc.etc.

What is the correct way to get the same behavior in the two cases?
Thank you

Try to define fTemplateCFShift and fTemplate as “static” variables.

Hi,
You need to make sure that the function TF1 is used within the scope of the variables passed to the lambda. Otherwise you need to make them global available.

Lorenzo

Declaring fTemplateCFShift and fTemplate as “static” solved the issue. Thank you.

Still I do not understand why the variables are in scope during the fitting section of the h->Fit(…) call but out of scope in the drawing section of the same method…

Hi,
The problem is that the drawing is not actually happening when calling h->Draw() but when calling h->Paint() that is done automatically when exiting the macro. You can force the drawing before by calling gPad->Update() after h->Draw()

Lorenzo