Search code examples
c++root-framework

Root - failed filling branch : memory-resident tree


I am trying to merge trees doing :

string filename_;
TList *list = new TList;

///Loop on all .root output files
for (int i = 1; i < 13; ++i) {
  string filename_ = "file_";
  string file_extension = ".root";
  stringstream ss;
  ss << i;
  string str = ss.str();
  filename_ = filename_+str+file_extension;
  const char* c_filename = filename_.c_str();
  TFile *file_adress = TFile::Open(c_filename);
  TTree *tree_adress = (TTree*)file_adress->Get("pulses");
  list->Add(tree_adress);
}

// Output tree:
TTree *TPulses = TTree::MergeTrees(list);

But I am getting this error, which is quietly explicite :

Error in <TTree::Fill>: Failed filling branch:pulses.pulse_time, nbytes=-1, entry=115710
 This error is symptomatic of a Tree created as a memory-resident Tree
 Instead of doing:
    TTree *T = new TTree(...)
    TFile *f = new TFile(...)
 you should do:
    TFile *f = new TFile(...)
    TTree *T = new TTree(...)

But I am creating the TFile before the TTree in the for loop, so I don't understand. Does someone have an idea ?


Solution

  • The error message you're seeing is from a TTree that you're writing to. As far as I understand your code, the TFile *file_adress and TTree *tree_adress are opened for reading and you write to TTree *TPulses. I don't see the default setting for TFile::Open (if it's READ for read-only or update for manipulating contents) but from your output I claim TPulses does not get created in the last file you open, but rather in RAM and you run out of that (see docs). A common pattern would be to create an output file before creating TPulses:

    TFile* outputfile = TFile::Open("output.root", "recreate");
    TTree* TPulses = TTree::MergeTrees(list);
    // ...
    TPulses->Write();
    outputfile->Close();
    delete outputfile;