root icon indicating copy to clipboard operation
root copied to clipboard

[Tree] Bogus data silently read when trying to access an indexed friend TTree with an invalid index

Open eguiraud opened this issue 4 years ago • 8 comments

  • [X] Checked for duplicates (checked with @pcanal )

Describe the bug

Reproducer:

#include <ROOT/RDataFrame.hxx>

int main() {
  {
    // write data out

    // in the main tree, "x" counts 0, 1, 2
    ROOT::RDataFrame(3)
        .DefineSlotEntry("x", [](unsigned, ULong64_t e) { return int(e); })
        .Snapshot<int>("main", "main.root", {"x"});

    // in the friend tree, "x" counts 0, 1, 3 (i.e. no entry with x == 2)
    ROOT::RDataFrame(3)
        .DefineSlotEntry("x",
                         [](unsigned, ULong64_t e) { return e == 2 ? 3 : int(e); })
        .Snapshot<int>("friend", "friend.root", {"x"});
  }

  TFile fmain("main.root");
  auto *main = fmain.Get<TTree>("main");
  TFile ffriend("friend.root");
  auto *fr = ffriend.Get<TTree>("friend");

  fr->BuildIndex("x");
  main->AddFriend(fr);

  int xmain, xfriend;
  main->SetBranchAddress("x", &xmain);
  main->SetBranchAddress("friend.x", &xfriend);

  for (int i = 0; i < 3; ++i) {
    main->GetEntry(i);
    std::cout << xmain << " " << xfriend << '\n';
  }

  return 0;
}

Expected behavior

An error or warning should be printed if no indexed entry could be retrieved.

eguiraud avatar Mar 26 '21 16:03 eguiraud

Adding the 6.26 milestone after discussion with Axel

eguiraud avatar Nov 12 '21 09:11 eguiraud

We have a related/similar issue with a TChain containing trees with missing branches:

f = new TFile("f1.root","RECREATE");
t1 = new TTree("t1","t1a")
int i = 55;
t1->Branch("a",&i);
t1->Branch("b",&i);
t1->Fill();
f->Write();
f = new TFile("f2.root","RECREATE");
t1 = new TTree("t1","t1b")
int i = -55;
t1->Branch("a",&i);
t1->Fill();
f->Write();
.q
c = new TChain("t1");
c->Scan("a")
c->Add("f1.root");
c->Add("f2.root");
c->Scan("a")
c->Scan("b")
c->Scan("")

prints:

************************
*    Row   *         a *
************************
*        0 *        55 *
*        1 *       -55 *
************************
(long long) 2
root [5] c->Scan("b")
************************
*    Row   *         b *
************************
*        0 *        55 *
*        1 *         0 *
************************
(long long) 2
root [6] c->Scan("")
************************************
*    Row   *       a.a *       b.b *
************************************
*        0 *        55 *        55 *
*        1 *       -55 *         0 *
************************************

pcanal avatar Jan 26 '23 16:01 pcanal

Do I understand correctly that this is in fact fixed? by #12260 ? Can this be closed? If not - do we need to delay v6.30/00 because of it?

Axel-Naumann avatar Oct 27 '23 12:10 Axel-Naumann

Hi, this is still an issue. TChain and TTree silently return the last valid value for an indexed friend tree if the main one asks for a non-existing index.

#12260 was a specific bug in RDF's multi-threading + indexed friend trees that users encountered and that would have been made immediately visible if this issue was fixed.

eguiraud avatar Oct 27 '23 14:10 eguiraud

So do we need to delay 6.30/00 because of this, @pcanal ? I guess not - my suspicion is that this exists since the beginning of time?

Axel-Naumann avatar Oct 27 '23 14:10 Axel-Naumann

This definitely exists since the beginning of time, and I completely understand the situation with the release. In fact, the same thing happened with 6.26 and then 6.28.

Just allow me to say that just because it's an old bug it does not make it less evil :smile:

eguiraud avatar Oct 27 '23 15:10 eguiraud

It's critical 🚨

Axel-Naumann avatar Oct 27 '23 15:10 Axel-Naumann

Should we maybe remove the "critical" label?

guitargeek avatar May 22 '24 16:05 guitargeek

Hi, this issue is causing us problems running differential cross-section measurements using RDataFrame. It is very common that you have events passing the detector level selection but not the truth level selection (often separate trees that you need to match). And I am not aware of any workaround directly from RDataFrame. We discussed a bit with @vepadulano and it would be ideal to provide a function that would allow users to check if a given friend event exists - this would allow the option for the users to filter on this and skip the problematic events.

TomasDado avatar Jul 10 '24 07:07 TomasDado

Hi @vepadulano, @pcanal, @dpiparo,

It appears this issue is closed, but wasn't yet added to a project. Please add upcoming versions that will include the fix, or 'not applicable' otherwise.

Sincerely, :robot:

github-actions[bot] avatar Oct 01 '24 06:10 github-actions[bot]