Issue with RooFit::Cut and RooFormula definition

Dear experts,
I am trying to understand the following issue.
I have a workspace from which I am trying to produce the plot of some quantity therein.
I am doing the following:

data = _file0.Get("toys/toys_asimov")
CMS_channel = w_asimov.cat("CMS_channel")
datacut = "CMS_channel==CMS_channel::hzz_mass4l_105p0_160p0_cat4e_2022 || CMS_channel==CMS_channel::hzz_mass4l_105p0_160p0_cat4e_2022EE"
data = data.reduce(RooFit.Cut(datacut))

Now, when I run the code above with ROOT 6.12/07, everything works as expected. However, if I run the same code with ROOT 6.22/09, I get the following error:

input_line_169:2:82: error: expected ';' after return statement
Double_t TFormula____id13173150475813404828(Double_t *x){ return x[1]==0||x[1]==0{EE} ; }
                                                                                 ^
                                                                                 ;
input_line_170:2:82: error: expected ';' after return statement
Double_t TFormula____id13173150475813404828(Double_t *x){ return x[1]==0||x[1]==0{EE} ; }
                                                                                 ^
                                                                                 ;
Error in <prepareMethod>: Can't compile function TFormula____id13173150475813404828 prototype with arguments Double_t*
Error in <TFormula::InputFormulaIntoCling>: Error compiling formula expression in Cling
Error in <TFormula::ProcessFormula>: "EE" has not been matched in the formula expression
Error in <TFormula::ProcessFormula>: Formula "x[1]==0||x[1]==0EE" is invalid !
[#0] FATAL:InputArguments -- RooFormula 'CMS_channel==CMS_channel::hzz_mass4l_105p0_160p0_cat4e_2022 || CMS_channel==CMS_channel::hzz_mass4l_105p0_160p0_cat4e_2022EE' did not compile or is invalid.
Input:
	CMS_channel==CMS_channel::hzz_mass4l_105p0_160p0_cat4e_2022 || CMS_channel==CMS_channel::hzz_mass4l_105p0_160p0_cat4e_2022EE
Passed over to TFormula:
	x[1]==0 || x[1]==0EE

The application of the cut without the || operator works, and the application of the cut with the || operator but mixed categories (eg ...cat4e_2022 || ..._cat4mu_2022EE) works too, but the cut as I would like to have it breaks the code.

Do you have any insight?

Thank you very much in advance!

best,
Matteo

Welcome to the ROOT Forum!
I think @jonas can help you with this

Chiao @Matteo_Bonanomi!

It seems that somewhere between ROOT 6.12 and 6.22, the RooFormula parsing was broken. This problem is still there in ROOT master and can be simply reproduced standalone:

RooCategory cat{"cat", "cat", {{"state_0", 0}, {"state_0_0", 1}}};
RooFormulaVar cut{"cut", "cat == cat::state_0 || cat == cat::state_0_0", cat};

Seems like the parsing of category states gets confused if one states name is a substring on the name of another state, as you can see also in the error message.

If you think this is worth fixing in ROOT, please open a GitHub issue about this, including my reproducer:

As for the existing ROOT releases, you can work around this by doing the translation from category state name to index yourself with RooAbsCategory::lookupIndex(), and then put the index in the formula. Like:

RooCategory cat{"cat", "cat", {{"state_0", 0}, {"state_0_0", 1}}};
std::stringstream expression;
expression << "cat == cat::state_0 || cat == " << cat.lookupIndex("cat::state_0_0");
RooFormulaVar cut{"cut", expression.str().c_str(), cat};

I hope this helps and greetings to Hamburg :smiley:

Cheers,
Jonas

Hi Jonas,
Thank you very much for the prompt reply and for the workaround: it works perfectly!

Greetings to you! :smiley:

Cheers,
Matteo

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