Skip to content

[treeplayer] Don't mistake formulas for script files in TTree::Draw - #22774

Merged
guitargeek merged 1 commit into
root-project:masterfrom
guitargeek:ROOT-8000
Aug 7, 2026
Merged

guitargeek merged 1 commit into
root-project:masterfrom
guitargeek:ROOT-8000

Conversation

@guitargeek

@guitargeek guitargeek commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

TTree::Draw can take the name of a C++ script file instead of a TTreeFormula expression for both the variable expression and the selection. To decide between the two, TTreePlayer::DrawSelect checked whether a matching file exists via TSystem::IsFileInIncludePath(), which strips a trailing parenthesized part as ACLiC-style macro arguments. A formula like "abs(Bs_TRUEID)" was thus reduced to "abs", and if an unrelated file with that name happened to exist in the current directory, the Draw call failed:

root [0] tree->Draw("Bs_MCORR", "abs(Bs_TRUEID)")
Error in <TTreePlayer::DrawSelect>: Drawing using a C++ macro
currently requires that both the expression and the selection are
files: "Bs_MCORR" is not a file

Two inconsistencies made the trap wider: the selection branch did not require a dot in the candidate string at all, and the varexp branch checked for a dot before stripping the arguments, so a decimal constant inside the parentheses (e.g. "abs(x+0.5)") satisfied it.

Factor the decision into a single helper used for both arguments, which requires the candidate - after stripping the ACLiC mode and arguments - to have an extension. This is not a new restriction: TTreeProxyGenerator::WriteProxy() already refuses a script without an extension (the function name is derived from the basename minus the extension, for the cut script too), so such a file could never be processed anyway. It now evaluates as a formula instead of failing with a misleading error.

Add regression tests that exercise the previously failing Draw calls in the presence of a shadowing file named "abs", and that check a real "abs.C" macro is still recognized as a script because of its extension.

Fixes https://its.cern.ch/jira/browse/ROOT-8000

🤖 Done with the help of AI

@github-actions

github-actions Bot commented Jul 8, 2026 •

Copy link
Copy Markdown

Test Results

    23 files      23 suites   3d 17h 14m 59s ⏱️
 3 877 tests  3 876 ✅ 0 💤 1 ❌
78 960 runs  78 959 ✅ 0 💤 1 ❌

For more details on these failures, see this check.

Results for commit f7edbf1.

♻️ This comment has been updated with latest results.

Comment thread tree/treeplayer/src/TTreePlayer.cxx Outdated
Comment thread tree/treeplayer/src/TTreePlayer.cxx Outdated
Comment thread tree/treeplayer/src/TTreePlayer.cxx Outdated

@dpiparo dpiparo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the opinion of @pcanal could be useful, however, for me the PR is good to go.

@jblomer jblomer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I think @pcanal should take a look, too.

Comment thread tree/treeplayer/src/TTreePlayer.cxx Outdated
Comment thread tree/treeplayer/test/regressions.cxx
`TTree::Draw` can take the name of a C++ script file instead of a
TTreeFormula expression for both the variable expression and the
selection. To decide between the two, `TTreePlayer::DrawSelect` checked
whether a matching file exists via `TSystem::IsFileInIncludePath()`,
which strips a trailing parenthesized part as ACLiC-style macro
arguments. A formula like `"abs(Bs_TRUEID)"` was thus reduced to
`"abs"`, and if an unrelated file with that name happened to exist in
the current directory, the Draw call failed:

```
root [0] tree->Draw("Bs_MCORR", "abs(Bs_TRUEID)")
Error in <TTreePlayer::DrawSelect>: Drawing using a C++ macro
currently requires that both the expression and the selection are
files: "Bs_MCORR" is not a file
```

Two inconsistencies made the trap wider: the selection branch did not
require a dot in the candidate string at all, and the varexp branch
checked for a dot before stripping the arguments, so a decimal
constant inside the parentheses (e.g. `"abs(x+0.5)"`) satisfied it.

Factor the decision into a single helper used for both arguments, which
requires the candidate - after stripping the ACLiC mode and arguments -
to have an extension. This is not a new restriction:
`TTreeProxyGenerator::WriteProxy()` already refuses a script without an
extension (the function name is derived from the basename minus the
extension, for the cut script too), so such a file could never be
processed anyway. It now evaluates as a formula instead of failing with
a misleading error.

Add regression tests that exercise the previously failing Draw calls in
the presence of a shadowing file named "abs", and that check a real
"abs.C" macro is still recognized as a script because of its extension.

Fixes https://its.cern.ch/jira/browse/ROOT-8000

🤖 Done with the help of AI
@guitargeek

Copy link
Copy Markdown
Contributor Author

@dpiparo and @jblomer, thanks for the review comments! I have addressed them.

@pcanal, you have something to add to the review by Danilo and Jakob?

Comment thread tree/treeplayer/src/TTreePlayer.cxx

@pcanal pcanal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@pcanal pcanal closed this Aug 6, 2026
@pcanal pcanal reopened this Aug 6, 2026
@pcanal

pcanal commented Aug 6, 2026

Copy link
Copy Markdown
Member

Closing and Reopening to trigger rebuild.

@guitargeek
guitargeek merged commit 58786cc into root-project:master Aug 7, 2026
32 of 34 checks passed
@guitargeek
guitargeek deleted the ROOT-8000 branch August 7, 2026 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants