Skip to content

Support ^ power operator and more TMath functions in TTree::Draw expressions - #425

Closed
Prafyl wants to merge 2 commits into
root-project:devfrom
Prafyl:fix-treedraw-power-tmath
Closed

Prafyl wants to merge 2 commits into
root-project:devfrom
Prafyl:fix-treedraw-power-tmath

Conversation

@Prafyl

@Prafyl Prafyl commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

This Pull request:

In ROOT ^ is the power operator in draw expressions, but jsroot passes the expression straight into a js function where ^ is like the bitwise xor operator thing. So tree.Draw("x^2") gives a histogram of x XOR 2, it doesnt give error but gives just wrong numbers. Also only TMath::Exp/Abs/Prob/Gaus were mapped, so things like TMath::Sqrt(x) or TMath::Pi() throw a syntax error on the ::.

values at x=3 from a small tree (x = 0..9), compared with TTree::Draw in ROOT 6.40:

expression           root        jsroot before   jsroot after
x^2                  9           1               9
-x^2                 -9          -1              -9
(x+1)^2              16          6               16
x^0.5                1.7320508   3               1.7320508
x^-1                 0.33333333  -4              0.33333333
2*x^2+1              19          5               19
x^2^0.5              3           1               3
TMath::Power(x,2)    9           SyntaxError     9
TMath::Sqrt(x)       1.7320508   SyntaxError     1.7320508
TMath::Pi()*x        9.424778    SyntaxError     9.424778
TMath::Max(x,5.)     5           SyntaxError     5
TMath::Sin(x)^2      0.019914857 SyntaxError     0.019914857

Changes:

  • ^ gets rewritten to ** before the expression is compiled. operands are taken as names, numbers, brackets or calls, so -x^2 stays -(x**2) and a^b^c goes frpm the left side to right side, both like ROOT does (2^3^2 is 64 in root).
  • added the usual TMath functions (Sqrt, Power, Log, Log10, Sin/Cos/Tan, ASin/ACos/ATan/ATan2, SinH/CosH/TanH, Floor, Ceil, Max, Min) plus TMath::Pi() and TMath::E(), mapped to the js Math equivalents.

things like tree_draw, tree_dump, tree_selector and tree_staged give the same output as before.

Fixes:

draw expressions using ^ or common TMath functions now give the same values as ROOT instead of different wrong numbers or a syntax error.

Only TMath::Exp, Abs, Prob and Gaus were mapped, so expressions like
TMath::Sqrt(x) or TMath::Pi() failed with a syntax error on '::'.
Map the common TMath functions to their Math equivalents and add
TMath::Pi() and TMath::E().
In ROOT '^' is the power operator in TTree::Draw expressions, in JS it is
bitwise XOR, so expressions like "x^2" silently gave wrong values.
Rewrite '^' to '**' before compiling the expression. Operands are taken
as names, numbers, brackets or calls, so "-x^2" is -(x**2) and "a^b^c"
is evaluated from the left, as in ROOT.
@linev

linev commented Oct 15, 2026

Copy link
Copy Markdown
Member

Do we need support of not existing TMath here?

It was done for TFormula/TF1 classes while there formula can be defined in C++ and should be supported on JavaScript.

But treeDraw() functionality fully defined in JavaScript and I see no reason to introduce artificial support of TMath methods

Same is about x^y. Why not use x**y or just Math.pow(x,y)

@Prafyl

Prafyl commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Fair point, i didnt notice the docs say draw expressions use js Math. I'll drop the TMath part.

The only reason i did ^ is that it doesnt fail, it silently gives xor. If someone copies an expression from a ROOT macro like x^2 they get a histogram that looks fine but has wrong numbers, and nothing tells them. If you'd rather not translate it i can just close this, or i could make ^ throw an error saying to use ** instead, whichever you prefer.

@linev

linev commented Oct 15, 2026

Copy link
Copy Markdown
Member

We do not need mimic C++ functionality here.

But it is valid point for TFormula - there we should care about translating C++ code to JavaScript.
And if ^ used there - one should translate it to JavaScript syntax.

If you interested - you can try extend functionality in the modules/base/func.mjs

@Prafyl

Prafyl commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, that makes sense, i realize treeDraw doesnt need it since its all js. I'll close this one and look into TFormula in func.mjs instead.

@Prafyl Prafyl closed this Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants