Using TTreeReader alongside other access methods / TTree::GetEntry vs TTree::LoadTree

Dear experts,

I was wondering if anyone could elaborate on the difference between TTree::GetEntry(…) and LoadTree(…).
The particular issue I’m concerned about is using a TTreeReader (which as far as I can see uses LoadTree to move through the input data) alongside other ways of accessing information from the input file/tree(s). Our current event loop uses TTree::GetEntry(…) and I’d therefore like to know if there is either

  • a TTreeReader would still be usable when not calling it’s Next() or SetEntry(…) methods but calling GetEntry(…) on the tree instead
  • or if I could simply switch to LoadTree(…) (or even just TTreeReader::Next() ) without affecting existing code running inside the event loop (which is generally not under my own control)

Any additional insight would be highly appreciated.
Cheers,
Ralf

HI Ralf,

LoadTree essential moves a cursor. It records which current entry to read. It takes on a more important role for a TChain where moving the cursor might also require opening the next file in the chain.

TTree::GetEntry and TBranch::GetEntry will actually read the data, i.e. make sure the data is read from the disk, uncompressed if needed and then unboxed into the user visible data field (eg. the address passed to SetBranchAddress).

so typically the loop looks like:

Long64_t nentries = fChain->GetEntriesFast();
for (Long64_t jentry=0; jentry<nentries;jentry++) {
   Long64_t localEntry = fChain->LoadTree(entry);
   if (localEntry < 0) return localEntry; // Opening the next file failed.
   if (readEverything) {
      fChain->GetEntry(jentry); 
  } else {
     // Read only the branch you need.
     fSomeBranch->GetEntry(localEntry);
  }
  ...
}

using a TTreeReader (which as far as I can see uses LoadTree to move through the input data)

It also uses TBranch::GetEntry to actually read the data when the reader’s content is being accessed.

Our current event loop uses TTree::GetEntry(…)

You are likely/possibly reading more of the data/branches that you really need/use. Using the TTreeReader will solve that automatically (alternatively you can get a pointer to the branch and call TBranch::GetEntry)

Cheers,
Philippe.

Hi Philippe,
thanks a lot for the reply, this has sorted my thoughts quite a bit.
I can’t really switch to purely using the TTreeReader as there’s a multitude of user code / analysis specifics executed during the loop, extracting information from the tree in various way (including, e.g., via classes of the ATLAS xAOD EDM). Hence, I’d like to stick with TTree::GetEntry for now (in addition we have a mechanism in place which can disable unused branches).
If was to provide a TTreeReader to user classes as an additional access option, would it be sufficient to only call GetEntry on the tree or do I need to explicitly step the reader as well? Assuming only a simple TTree (no TChain), are the two following examples expected to behave differently?

for(Long64_t entry=0; entry<maxEntries;entry++) {
    //not calling reader->SetEntry(entry);
    tree->GetEntry(entry);
    //calls to user code analyzing the event here, potentially using the reader
}

compared to

for(Long64_t entry=0; entry<maxEntries;entry++) {
    reader->SetEntry(entry);
    tree->GetEntry(entry);
    //calls to user code analyzing the event here, potentially using the reader
}

Once analyses had ample time to switch from plain tree access to using the (then provided) reader I imagine one could simply drop the TTree::GetEntry call in the second example.

Do you see any (subtle) issue arising in this concept?

Cheers,
Ralf

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.