Issues with getting data with SetBranchAddress

Hello all,

I’m a novice with ROOT, so apologies in advance if this is a trivial issue.
I’m using a modified ROOT version 4.04/02g, that is linked with some class definitions from our experiment.

Simply, I’m trying to have ROOT print out the entries in a branch one at a time, similar to the results of using Scan. I’ve attached the root file “small.root”.

In the tree “Experiment”, the branch I want to print out is “TGlobalTankHeaderChunk.data_.RUN_NUM”. When I use MakeClass to set up my macro, I successfully print out the variables for each event one at a time. I’ve attached these as Experiment.C and Experiment.h. Experiment.C looks like

#define Experiment_cxx
#include "Experiment.h"
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>

void Experiment::Loop()
{

   if (fChain == 0) return;


    Long64_t nentries = fChain->GetEntriesFast();
    Int_t run_num;
    Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", &run_num);

   Int_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);   nbytes += nb;
      // if (Cut(ientry) < 0) continue;
      //

    cout<< run_num<<endl;
   }
}

But when I try to write my own macro from scratch, I end up getting 0’s for every event. I’ve attached that file as readdata.C. I tried to keep things close to Experiment.C, but it doesn’t work. Here is readdata.C

void readdata(){

    TFile *f = new TFile("small.root");

    TTree* Experiment = (TTree*)f->Get("Experiment");
    Int_t run_num;
    Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", &run_num);
    Long64_t nentries = Experiment->GetEntries();

    for ( Long64_t  jentry = 0 ; jentry < nentries; ++jentry){

        Experiment->GetEntry(jentry);
        std::cout<<run_num<<std::endl;

    }

    return;
}

I also noticed that when I used Experiment->Print(), it looks like the branch I’m interested in is an array, with length 1. I tried changing the lines

Int_t run_num;
...
Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", &run_num);
...
std::cout<<run_num<<std::endl;

to

Int_t run_num[1];
...
Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", run_num);
...
std::cout<<run_num[0]<<std::endl;

But that didn’t seem to work.

Does anybody have any tips?

I hope this isn’t too silly, but I’ve spent quiet a bit of time trying to figure this out.

small.root (36.9 KB)
Experiment.h (4.0 KB)
Experiment.C (1.6 KB)
readdata.C (636 Bytes)

Try

auto b = Experiment->GetBranch("TGlobalTankHeaderChunk.data_.RUN_NUM");
if (b) b->SetMakeClass(true);
Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", &run_num);

Alternatively investigate using TDataFrame instead. ( [TDataFrame](https://root.cern.ch/doc/master/classROOT_1_1Experimental_1_1TDataFrame.html 1 ; TDF Tutorials ).

Thanks for the response!

I made the changes

void readdata(){

    TFile *f = new TFile("small.root");

    TTree* Experiment = (TTree*)f->Get("Experiment");
    Int_t run_num;

    auto b = Experiment->GetBranch("TGlobalTankHeaderChunk.data_.RUN_NUM");
    if (b) b->SetMakeClass(true);
    Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", &run_num);
    Long64_t nentries = Experiment->GetEntries();

    for ( Long64_t  jentry = 0 ; jentry < nentries; ++jentry){

        Experiment->GetEntry(jentry);
        std::cout<<run_num<<std::endl;

    }

    return;
}

But I get the following error

Error: Can't call TBranch::SetMakeClass(true) in current scope FILE:readdata.C LINE:10
Possible candidates are...
filename       line:size busy function type and name  (in TBranch)
filename       line:size busy function type and name  (in TNamed)
filename       line:size busy function type and name  (in TObject)
filename       line:size busy function type and name  (in TAttFill)
Error: Symbol b is not defined in current scope  FILE:readdata.C LINE:10
Error: Failed to evaluate b->SetMakeClass(true)Possible candidates are...
filename       line:size busy function type and name  
*** Interpreter error recovered ***

And I think that TDataFrame is not included in the version of ROOT provided to me.

I just noticed that you are using a very ancient version of ROOT (4.04/02g,). TBranch::SetMakeClass was introduced in v5.28/00 release in 2010 …

Nonetheless the following should work with your release

Experiment->SetMakeClass(true);
Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", &run_num);

Cheers,
Philippe.

Yeah, it’s from an old experiment…

So I tried that:


    TFile *f = new TFile("small.root");

    TTree* Experiment = (TTree*)f->Get("Experiment");
    Int_t run_num;

    Experiment->SetMakeClass(true);
    Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", &run_num);
    Long64_t nentries = Experiment->GetEntries();

    for ( Long64_t  jentry = 0 ; jentry < nentries; ++jentry){

        Experiment->GetEntry(jentry);
        std::cout<<run_num<<std::endl;

    }

    return;
}

And I get the following error now:

Processing readdata.C...

 *** Break *** segmentation violation
 Generating stack trace...
/miniboone/app/app/BooNE_products/gcc/v3_4_6/Linux64bit+2.6-2.12/bin/addr2line: 'MiniBooNEroot': No such file
 0x00a98adb in TBuffer::operator>>(int&) + 0x13 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCore.so
 0x0151e079 in TBranchElement::ReadLeaves(TBuffer&) + 0x63 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libTree.so
 0x0150e510 in TBranch::GetEntry(long long, int) + 0x284 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libTree.so
 0x0151cba9 in TBranchElement::GetEntry(long long, int) + 0x91 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libTree.so
 0x015488ea in TTree::GetEntry(long long, int) + 0xc4 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libTree.so
 0x01565929 in <unknown> from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libTree.so
 0x00264a05 in G__call_cppfunc + 0x338 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x002513df in G__interpret_func + 0x84f from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x00227860 in G__getfunction + 0x1993 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x002e6b27 in G__getstructmem + 0xaad from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x002dc411 in G__getvariable + 0x7b9 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x0021aa88 in G__getitem + 0x804 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x002189c1 in G__getexpr + 0xac3c from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x00283597 in G__exec_function + 0xd7 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x0028d275 in G__exec_statement + 0x436e from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x002881b7 in G__exec_loop + 0x29e from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x00288aad in G__exec_for + 0x26a from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x0028cf56 in G__exec_statement + 0x404f from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x00252e71 in G__interpret_func + 0x22e1 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x0022814f in G__getfunction + 0x2282 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x0021aac8 in G__getitem + 0x844 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x002189c1 in G__getexpr + 0xac3c from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x0020d909 in G__calc_internal + 0x416 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x00293fed in G__process_cmd + 0x2667 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCint.so
 0x00b43dcb in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) + 0xbb from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCore.so
 0x00b43f0d in TCint::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) + 0x4f from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCore.so
 0x00a88421 in TApplication::ProcessFile(char const*, int*) + 0x753 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCore.so
 0x00a87c41 in TApplication::ProcessLine(char const*, bool, int*) + 0x64b from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libCore.so
 0x00418a7f in TRint::Run(bool) + 0x285 from /miniboone/app/app/BooNE_products/root/v4_04_02g/Linux-2-6-2-12-GCC_3_4_6/lib/libRint.so
 0x08415a71 in main + 0xa9 from MiniBooNEroot
 0x01d6ed26 in __libc_start_main + 0xe6 from /lib/libc.so.6
 0x08415961 in <unknown> from MiniBooNEroot
Root > Function readdata() busy flag cleared

There’s a lot of reference to my experiment, so it might be an issue on my end. Near the top, “MiniBooNEroot” is the modified version of root we use. Could the issue lie there?

I appreciate all your help :slight_smile:

Humm … then execute

Experiment->MakeClass("skel");

and look at the resulting file to make sure you are using the right types.

So that would just give me the same things as Experiment.C and Experiment.h that I had attached on my first post, right?

In the header file, I do find

Int_t           TGlobalTankHeaderChunk_data__RUN_NUM[kMaxTGlobalTankHeaderChunk]; 

and a few lines above

const Int_t kMaxTGlobalTankHeaderChunk = 1;

Like I mentioned earlier, this just looks to me like an array with 1 element. But when I tried to make the changes:

Int_t run_num;
...
Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", &run_num);
...
std::cout<<run_num<<std::endl;

to

Int_t run_num[1];
...
Experiment->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", run_num);
...
std::cout<<run_num[0]<<std::endl;

I still got the same issue where I just got a bunch of 0s.

#include "TFile.h"
#include "TTree.h"

#include <iostream>

void readdata(void) {
  TFile *f = new TFile("small.root");
  TTree *t = (TTree*)f->Get("Experiment");
  
  Int_t chunk; // actual size (tree entry dependent)
  const Int_t max_chunk = 1; // max size (as retrieved by MakeClass)
  Int_t run_num[max_chunk];
  
  t->SetMakeClass(1); // all branches in decomposed object mode
  t->SetBranchAddress("TGlobalTankHeaderChunk", &chunk);
  t->SetBranchAddress("TGlobalTankHeaderChunk.data_.RUN_NUM", run_num);
  
  // if some ancient ROOT doesn't know Long64_t, simply use Int_t instead
  Long64_t n = t->GetEntries();
  for (Long64_t i = 0; i < n; i++) {
    t->GetEntry(i);
    std::cout << i << " : " << chunk << " :";
    if (chunk > max_chunk) { // just a precaution
      std::cout << " !!! STACK CORRUPTION !!!" << std::endl;
      break;
    }
    for (Int_t j = 0; j < chunk; j++) {
      std::cout << " " << run_num[j];
    }
    std::cout << std::endl;
  }
  
  // t->ResetBranchAddresses(); // "disconnect" from local variables
  delete f; // automatically deletes "t", too
}

That worked! Thanks a lot! So the difference in this case was that we used SetMakeClass(1) and set the branch address for “TGlobalTankHeaderChunk”? I’ll have to learn why that made it work.

I really appreciate the help, thanks a lot!

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