Skip to content

Conversation

@silverweed
Copy link
Contributor

This Pull request:

adds TTree reading support in RFile by registering it to the internal TFile when calling Get<TTree>.

Checklist:

  • tested changes locally
  • updated the docs (if necessary)


{
auto file = ROOT::Experimental::RFile::Open(fileGuard.GetPath());
auto tree = file->Get<TTree>("tree");
Copy link
Member

Choose a reason for hiding this comment

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

Could you close the file and check the tree after closing? It likely breaks, but is the tree still touchable (albeit in an invalid state)?
(I assume it's the latter)

Can the tree complain that its file is gone?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Accessing the tree after closing the file causes a segfault - same as with TFile.
If we want to fix it it could not be an RFile-related fix but it should be either in TTree of TFile probably...

Copy link
Member

Choose a reason for hiding this comment

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

I fully understand, but we should ask ourselves the question whether handing out a unique_ptr<TTree> makes sense in that case. It promises something that we (as of now) cannot guarantee.
@dpiparo what do you think?

Copy link
Member

Choose a reason for hiding this comment

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

So maybe, as a way forward, we can see to merging this PR, but we should work on a solution later on that doesn't lead to crashes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree that the unique_ptr is somewhat semantically wrong, but I would refrain from compromising the API for this special case; I think we should absolutely try to better detect this on the TFile/TTree side and print out a nice error message rather than crashing (though I suspect if it were that simple it would have already been done a long time ago..)

Copy link
Member

Choose a reason for hiding this comment

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

Maybe it can be done in the RFile side:

  • When destructing RFile, check the list of the underlying TFile.
  • Finding something that inherits from TTree, you could call addDirectoryFunction(tree, nullptr);
  • This should remove it from the list of managed objects, so the TTree should survive the file closing.

If TTree::SetDirectory(nullptr) does the right thing (a brief look at the code seems to go in the right direction), you should now have a standalone tree.

Is this worth trying in the scope of this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps, but a quick test revealed that probably that's not sufficient, and even if it were we would be paying a performance price for every RFile deletion, which is less than ideal...

Copy link
Member

Choose a reason for hiding this comment

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

One thing (aka a hack) RFile could do is mark the TTree object as being on the stack (ie. inaccurate but with the desired side-effect), this would lead the Close of the TFIle to no longer attempt to delete the TFile. [Side note: in essence the TFile holds a link that is akin to a shared_ptr while the user hold a link that akin to a weak_ptr ... except that the link is not nullptr-ed when the TTree is deleted ... Where the analogy fails is that user can also explicitly delete the TTree]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Besides it being a hack, wouldn't the hack also cause the TTree not to be automatically written upon file close?
I'd rather keep the same behavior between TFile and RFile and solve (or at least mitigate) the problem on the lower level so it benefits both

Copy link
Member

@pcanal pcanal Jan 29, 2026

Choose a reason for hiding this comment

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

Besides it being a hack, wouldn't the hack also cause the TTree not to be automatically written upon file close?

No. It literally only affects whether the object is deleted or not when 'Clear'ing the list of owner objects. (Note with TFile the Write of the TTree meta-data (the object itself) is not implicit).

I'd rather keep the same behavior between TFile and RFile and solve (or at least mitigate) the problem on the lower level so it benefits both

The significant difference is that RFile returns a unique_ptr ... which actually already both mitigate and worsen the issue.

The problematic pattern is:

auto file = TFile::Open(....);
auto tree = file->Get<TTree>(...);
...
delete file;
delete tree; // or do anything with the TTree

The recommendation for TFile is to either not delete the TTree or delete it early:

auto file = TFile::Open(....);
auto tree = file->Get<TTree>(...);
...
delete tree; // This is fine, the TFile is warned of the deletion ... alternatively you can skip this line
delete file;

With RFile the variable are both unique_ptr and thus will be delete in the 'right' order unless the user intervenes and directly or indirectly does:

      auto file = ROOT::Experimental::RFile::Open(...);
      auto tree = file->Get<TTree>(...);
      // Calling either:
      file->Close();
      // or
      file.reset();
      // lead to a double delete by `tree`

If we support RFile writing TTree there is also question on when/where the Write of the TTree meta-data (the TTree object itself) is triggered (if it is during the deletion of the RFile then we are in trouble).

@github-actions
Copy link

github-actions bot commented Jan 27, 2026

Test Results

    22 files      22 suites   3d 17h 39m 21s ⏱️
 3 774 tests  3 773 ✅ 0 💤 1 ❌
75 059 runs  75 058 ✅ 0 💤 1 ❌

For more details on these failures, see this check.

Results for commit 71d7dfc.

♻️ This comment has been updated with latest results.

Copy link
Member

@hageboeck hageboeck left a comment

Choose a reason for hiding this comment

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

Approved if we fix the ruff failure and open an issue regarding the dangling pointer to the TTree if the file is closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants