Check whether TString contains a valid TFormula

Hi,

I’m wondering whether there is a way to check whether a TString contains a valid TFormula without throwing an error.

When trying e.g.

root [0] TFormula fml("","si(x)")

I get the error

input_line_35:2:65: error: use of undeclared identifier 'si'
Double_t TFormula____id3732792798741230608(Double_t *x){ return si(x[0]) ; }
                                                                ^
input_line_36:2:65: error: use of undeclared identifier 'si'
Double_t TFormula____id3732792798741230608(Double_t *x){ return si(x[0]) ; }
                                                                ^
Error in <prepareMethod>: Can't compile function TFormula____id3732792798741230608 prototype with arguments Double_t*
Error in <TFormula::InputFormulaIntoCling>: Error compiling formula expression in Cling
Error in <TFormula::ProcessFormula>: Formula "si(x)" is invalid !
(TFormula &) Name:  Title: si(x)

and the exact same error for

TFormula fml("",""); fml.SetTitle("si(x)"); fml.Compile()

There is a method IsValid(), but this can only be called after Compile (throwing an error for an invalid formula anyways). The codes continues running, but I’d like to suppress this error output.

Best regards and thanks,
Klaus


ROOT Version: 6.28/04
Platform: Linux Debian 10.13
Compiler: Not Provided


Hi Klaus,

I do not have an answer to your question. Maybe @moneta might be able to help you.

Cheers,
Devajith

Indeed you can silence this error. You can forward the interpreter output to the ROOT error handler, and then replace the ROOT error handler with a function that does nothing.

Here is an example, using a custom class that does what I described as long as it is alive:

void errorHandlerCallback(int severity,
                          bool abort,
                          const char * location,
                          const char * msg)
{
   // Do nothing, meaning all errors are suppressed.
}

class SilenceAllErrorsRAII {
public:
    SilenceAllErrorsRAII() : fOldErrorHandler{::GetErrorHandler()} {
        ::SetErrorHandler(errorHandlerCallback);
        gInterpreter->ReportDiagnosticsToErrorHandler(true);
    }
    ~SilenceAllErrorsRAII() {
        ::SetErrorHandler(fOldErrorHandler);
        gInterpreter->ReportDiagnosticsToErrorHandler(false);
    }
private:
    ErrorHandlerFunc_t const fOldErrorHandler = ::GetErrorHandler();
};

void demo()
{
    {
        // All errors will be silenced as long a "silencer" is alive,
        // meaning until the end of this scope. It's better to only
        // silence errors in the part of the code where you expect
        // them, otherwise you might miss important info.
        SilenceAllErrorsRAII silencer;

        TFormula fml("","si(x)");
    }
}

I hope this is what you’re looking for!

Cheers,
Jonas

1 Like

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