Accessing variables via SetBranchAddress

Hi everyone,

I’m having problems accessing the variables for a given tree. Usually it worked for me like in the code example, but now it just says “unknown branch”:

    TFile *f = new TFile("selected.root");
    TTree *mytree=(TTree*)f->Get("recData");

    Float_t fEnergy;
    mytree->SetBranchAddress("fEnergy",&fEnergy);

    for(Int_t i = 0; i <mytree->GetEntries(); i++){
    mytree->GetEntry(i);
    cout << fEnergy<< endl;
    }

I think that I set the address incorrectly, although I tried variations like the full pathname (event.fFDEvents.fFdRecShower.fEnergy). Please see the attached screenshot of the tree-structure.
Thanks!


In general, one would need your root file in order to try it, but as a first step you could try to use the “full name” of the branch which is something like “event.fFDEvents.fFdRecShower.fEnergy” (if it doesn’t work, either attach your root file here or put it somewhere in a “public area”, e.g. “afs”).

Ok, here is the link:
dropbox.com/s/xevxtlb1cbzc6 … .root?dl=0

See:

Try:

{
  TFile *f = TFile::Open("selected.root");
  if (!f) return; // just a precaution
  
  TTree *t; f->GetObject("recData", t);
  if (!t) { delete f; return; } // just a precaution
  
  t->SetMakeClass(1);
  t->SetBranchStatus("*", 0);
  
  Int_t fFDEvents_;
  // note: you must know kMaxevent_fFDEvents from somewhere else,
  //       e.g. use TTree::MakeClass to get it
  const Int_t kMaxevent_fFDEvents = 3;
  Double_t fEnergy[kMaxevent_fFDEvents]; //[fFDEvents_]
  
  t->SetBranchStatus("event.fFDEvents", 1);
  t->SetBranchAddress("event.fFDEvents", &fFDEvents_);
  
  t->SetBranchStatus("event.fFDEvents.fFdRecShower.fEnergy", 1);
  t->SetBranchAddress("event.fFDEvents.fFdRecShower.fEnergy", fEnergy);
  
  for(Long64_t i = 0; i < t->GetEntries(); i++) {
    t->GetEntry(i);
    
    if (fFDEvents_ > kMaxevent_fFDEvents) {
      // note: the stack is corrupt, a SIGSEV crash is possible
      std::cout << i << " : " << fFDEvents_ << " :"
                << " FATAL ERROR : fFDEvents_ > kMaxevent_fFDEvents = "
                << kMaxevent_fFDEvents << std::endl;
      delete f; // automatically deletes "t", too
      return; // try to get out of here
    }
    
    std::cout << i << " : " << fFDEvents_ << " :";
    for (Int_t j = 0; j < fFDEvents_; j++) std::cout << " " << fEnergy[j];
    std::cout << std::endl;
  }
  
  // t->ResetBranchAddresses(); // detach "t" from local variables
  delete f; // automatically deletes "t", too
}

Thank you very much! :slight_smile:

Dear ROOT experts,

I thought reviving this old thread would be the most straightforward way to ask you for help with reading the same file format as discussed here.

The code snippet provided Wile_E_Coyote works perfectly and is of great help.

My problem is that I can not get data from a branch with TVector3.

Br   87 :event.fFDEvents.fFdRecShower.fAxisCoreCS :
TVector3 fAxisCoreCS[event.fFDEvents_]

I tried to see if using MakeClass helps (generating and loading TVector3 dictionary does not change the outcome):

[] recData->MakeClass("recData");

The result is that the branch is filled with zeroes, while for GenShower (which is a scalar unlike FDEvents) it works:

[] .L recData.C
[] recData t
[] t.GetEntry(0)
[] t.Show()
======> EVENT:0
 event.fFDEvents = 1
 event.fFDEvents.fFdRecShower.fAxisCoreCS = 1
 event.fGenShower.fAxisCoreCS = TVector3

[] t.event_fFDEvents_fFdRecShower_fAxisCoreCS[0].Z()
(double) 0.0000000
[] t.event_fGenShower_fAxisCoreCS.Z()
(double) 0.82028817

In the original root file the values are:

[] [5] recData->Scan("event.fFDEvents.fFdRecShower.fAxisCoreCS.Z():event.fGenShower.fAxisCoreCS.Z()")
***********************************************
*    Row   * Instance * event.fFD * event.fGe *
***********************************************
*        0 *        0 * 0.8220908 * 0.8202881 *

MakeClass produces the following code for the respective branches:

   TTree          *fChain;   //!pointer to the analyzed TTree or TChain

   const Int_t kMaxevent_fFDEvents = 3;

   TVector3        event_fFDEvents_fFdRecShower_fAxisCoreCS[kMaxevent_fFDEvents];
   TVector3        event_fGenShower_fAxisCoreCS;

   TBranch        *b_event_fFDEvents_fFdRecShower_fAxisCoreCS;
   TBranch        *b_event_fGenShower_fAxisCoreCS;

   fChain->SetBranchAddress("event.fFDEvents.fFdRecShower.fAxisCoreCS", event_fFDEvents_fFdRecShower_fAxisCoreCS, &b_event_fFDEvents_fFdRecShower_fAxisCoreCS);
   fChain->SetBranchAddress("event.fGenShower.fAxisCoreCS", &event_fGenShower_fAxisCoreCS, &b_event_fGenShower_fAxisCoreCS);

I am attaching recData.{C,h} and the original root file.
I use ROOT 5.34/38 which is a prerequisite for working with this file.

Many thanks!

All the best,
Alexey

pico.root (84.3 KB)
recData.C (1.4 KB)
recData.h (72.0 KB)

Dear ROOT experts,

if this is difficult to answer, I think I will just non-elegantly circumvent the problem by dumping the content of this branch with Draw(…, “goff”), though I remain curious how one could reach this memory chunk with SetBranchAddress.

Alexey

Dear ROOT experts,

I am still puzzled about this problem. With Python it takes no effort, but how this chunk of memory can be nailed with C? I am attaching a minimum example [one of many options that I tried] just in case someone at least comes up with an explanation of why values from this branch can not be (?) accessed with SetBranchAddress.





readTreeLastTry.C (2.4 KB)