Problem using a function from a namespace in the formula of a TF1

Hi all,

When defining a TF1, it is possible to use functions from the namespace TMath in the formula string. Good.
However, when I try to use a function which is defined in my own nested namespaces, it doesn’t work. It doesn’t work either when there is only one namespace.

The function I want to use is

Double_t UtilityFunc::Astro::HubbleParameter(Double_t z)

The error message I get when running the code is the following, where you see the TFormula string as it is when creating the TF1:

input_line_9:2:97: error: use of undeclared identifier ‘UtilityFunc’

Double_t TFormula____id3995498473248415962(Double_t *x){ return TMath::Power((1+x[0]),2.000000)/UtilityFunc::Astro::HubbleParameter(x[0]) ; }

The header for the namespace UtilityFunc is included in the file where the TF1 is defined.
I also tried to add the following lines to the LinkDef header:

#pragma link C++ namespace UtilityFunc;
#pragma link C++ namespace UtilityFunc::Astro;
#pragma link C++ function UtilityFunc::Astro::HubbleParameter(Double_t);
but it doesn’t change anything

Since the formula is initially provided in a JSON file as a string, it would be very convenient for me to keep defining the TF1 from a formula string, and not e.g. a functor or a lambda.

It seems like the header UtilityFunc is not within reach when the TFormula is created at runtime.
Is there a way to make this work?

Thanks a lot for your help and all the best!
Julien

Here is a copy of the error messages :

input_line_9:2:97: error: use of undeclared identifier ‘UtilityFunc’
Double_t TFormula____id3995498473248415962(Double_t *x){ return TMath::Power((1+x[0]),2.000000)/UtilityFunc::Astro::HubbleParameter(x[0]) ; }
^
input_line_10:2:97: error: use of undeclared identifier ‘UtilityFunc’
Double_t TFormula____id3995498473248415962(Double_t x){ return TMath::Power((1+x[0]),2.000000)/UtilityFunc::Astro::HubbleParameter(x[0]) ; }
^
Error in : Can’t compile function TFormula____id3995498473248415962 prototype with arguments Double_t

Error in TFormula::InputFormulaIntoCling: Error compiling formula expression in Cling
Error in TFormula::ProcessFormula: Formula “pow((1+x[0]),1.000000)/UtilityFunc::Astro::HubbleParameter(x[0])” is invalid !
Error in TFormula::Eval: Formula is invalid and not ready to execute
UtilityFunc::Astro::HubbleParameter is unknown.
Error in TFormula::Eval: Formula is invalid and not ready to execute
UtilityFunc::Astro::HubbleParameter is unknown.

_ROOT Version: 6.28/06
_Platform: macosx64, installed using brew
_Compiler: Apple clang version 14.0.3


Let me add that replacing the function by its expression in the TFormula would be possible in that case, but I would still have the exact same problem with another function (defined in the same namespace), in which there is an integral, the integral of function HubbleParameter(z).

And I think it is anyway interesting to know how to deal with user-defined namespaces in TF1 construction.

Since my previous message, I found out that is it not necessary anymore to declare functions in the LinkDef.h file, so I just kept this in it:

#pragma link C++ namespace UtilityFunc;
#pragma link C++ namespace UtilityFunc::Astro;

Thanks in advance!
Julien

Hi,
You can use user defined functions in TFormula, but you need to make them available to the interpreter, Cling. Either you define them before or , if working at the ROOT interpreter, you can just include the file defining them.
Example:

gInterpreter->Declare("double f(double x) { return x*x;}");
TFormula ftest("ftest","f(x)");

or:

gInterpreter->Declare("#include \"MyFunction.h\"");
TFormula ftest("ftest","MyFunction(x)");

Lorenzo

Thanks a lot! :+1:

Actually I have one more question: what is the proper way to deal with namespaces in the LinkDef.h file?
Is it good enough to have these lines only? Do we need something else?

#pragma link C++ namespace UtilityFunc;
#pragma link C++ namespace UtilityFunc::Astro;

I think @pcanal can clarify better on this

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