Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tree] Fix interaction between GetEntries and GetListOfFriends #17822

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

vepadulano
Copy link
Member

Fixes #17820

Full analysis of the issue follows:

  1. TChain::GetEntries calls TChain::LoadTree(TTree::kMaxEntries - 1)

  2. Internally, this will set fReadEntry == -2, due to how LoadTree works and the fact it's trying to read beyond the last entry in the chain

  3. This has an effect here

    root/tree/tree/src/TChain.cxx

    Lines 1675 to 1679 in f33985d

    if (treeReadEntry == -2) {
    // an entry after the end of the chain was requested (it usually happens when GetEntries is called)
    t->LoadTree(entry);
    } else {
    t->LoadTreeFriend(entry, this);
    where t is the current friend being traversed in the list of friends of the chain. We call t->LoadTree(TTree::kMaxEntries - 1).

  4. Inside the call to LoadTree on the friend, we reach this line

    InvalidateCurrentTree();
    where the fTree data member of the friend is invalidated.

  5. Back to the LoadTree of the main chain, these lines

    root/tree/tree/src/TChain.cxx

    Lines 1681 to 1684 in f33985d

    TTree* friend_t = t->GetTree();
    if (friend_t) {
    auto localfe = fTree->AddFriend(t, fe->GetName());
    localfe->SetBit(TFriendElement::kFromChain);
    would normally connect the fTree data member of the main chain to the current friend, so the list of friends is properly populated. But due to 4., friend->GetTree() will return nullptr so the connection won't happen.

This commit fixes the issue by always calling LoadTreeFriend on the friend, which will anyway call LoadTree eventually but with the index value and does not incur in the wrong mechanics.

Fixes root-project#17820

Full analysis of the issue follows:

1. TChain::GetEntries calls TChain::LoadTree(TTree::kMaxEntries - 1)

2. Internally, this will set fReadEntry == -2, due to how LoadTree works and the
   fact it's trying to read beyond the last entry in the chain

3. This has an effect here https://github.com/root-project/root/blob/f33985dca2d6bc505e83498f7b4561ddd969be17/tree/tree/src/TChain.cxx#L1675-L1679
   where `t` is the current friend being traversed in the list of friends of the *chain*.
   We call `t->LoadTree(TTree::kMaxEntries - 1)`.

4. Inside the call to LoadTree on the friend, we reach this line
   https://github.com/root-project/root/blob/f33985dca2d6bc505e83498f7b4561ddd969be17/tree/tree/src/TChain.cxx#L1484
   where the fTree data member of the friend is invalidated.

5. Back to the LoadTree of the main chain, these lines
   https://github.com/root-project/root/blob/f33985dca2d6bc505e83498f7b4561ddd969be17/tree/tree/src/TChain.cxx#L1681-L1684
   would normally connect the fTree data member of the main chain to the current friend, so the list of friends
   is properly populated. But due to 4., `friend->GetTree()` will return nullptr so the connection won't happen.

This commit fixes the issue by always calling LoadTreeFriend on the friend,
which will anyway call LoadTree eventually but with the index value and does not
incur in the wrong mechanics.
@vepadulano vepadulano self-assigned this Feb 25, 2025
@vepadulano
Copy link
Member Author

Note that the current change apparently fixed the attached reproducer on my local machine, but evidently something is still missing. Suggestions on how to proceed are welcome!

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.

Wrong interaction between indexed TTree friend, GetEntries, GetListOfFriends
1 participant