TTree sorting on lxplus batch mode

Ok, here is the macro I used:

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

void sortS(){
TFile * f = new TFile("/tmp/Run10_list.root", "READ");

TTree *t;
f->GetObject("C_data",t);
TFile * f_out = new TFile(Form("/tmp/output.root"),"RECREATE");

// Create index on tunix branch (time)
Int_t nb_idx = t->BuildIndex("trigID","0");
TTreeIndex *att_index = (TTreeIndex*)t->GetTreeIndex();
TTree* to = (TTree*)t->CloneTree(0); // Problematic line

to->SetName("C_data");
to->SetDirectory(f_out);
// Loop on t_raw entries and fill t
//for( Long64_t i = 0; i < att_index->GetN(); i++ ) {
//Running on 10k events for starters because it's faster
for( Long64_t i = 0; i < 10000; i++ ) {
    t->GetEntry( att_index->GetIndex()[i]) ;
    to->Fill();
}

f_out->WriteTObject(to);
f_out->Close();

}

With it, I get the following crash using ROOT master, when calling TTree* to = (TTree*)t->CloneTree(0):

Fatal in <TBufferFile::WriteFastArray>: Not enough space left in the buffer (1GB limit). 522027660 elements is greater than the max left of 268317223
aborting

The reason is that, when cloning the TTree, even if you set entries=0, your generated TTreeIndex is also cloned (streamed), and it’s rather big to be processed at once by ROOT buffers.
R__b.WriteFastArray(fIndexValues, fN);
fIndexValues are 64-bit, 522027660 elements, so it exceeds the maximum size of 1GB per object in ROOT. See Overcome 1GB size limit for IO buffers · Issue #6734 · root-project/root · GitHub

So the solution is easy:
Call t->SetTreeIndex(0) before t->CloneTree(0),
or clone the Tree before building the index :wink:
Either way, no crash will happen.

TTree* to = (TTree*)t->CloneTree(0); // No longer problematic line
Int_t nb_idx = t->BuildIndex("trigID","0");

@pcanal if CloneTree is called with nentries different from -1, maybe the tree index should be internally disabled before and reenabled after the call to ::Clone()?

1 Like