I’m trying to write a simple code to filter an ntuple based on some criteria. What I do is basically reading a TTree from a file to memory, removing some entries from it, sorting it, then writing it back to the file. I end up with a file that is double the size of the original file.
TFile f("myfile.root", "READ");
gROOT->cd(0); // Forces a memory resident tree
TTree* t = (TTree*) f.Get("myTree");
TTree* newT = t->CopyTree("selection"); // Filtering
f.cd(0); // Prepare to write tree to file
newT->Write("", TObject::kOverwrite();
f.Close();
[quote] I end up with a file that is double the size of the original file. [/quote]This is the expected result since the original data is still in the file.
‘newT->Write("", TObject::kOverwrite();’ only overwrites the meta data (i.e. the TTree object itself describing the content) but does not overwrite nor delete the data.
What you ought do to is create a new file (that you can later rename to have the old filename):TFile f("myfile.root", "READ");
TTree* t = (TTree*) f.Get("myTree");
TFile out("selection.root","RECREATE");
TTree* newT = t->CopyTree("selection"); // Filtering
out.Write();
f.Close();
Int_t table[t->GetEntries()];
int minRun = (int) t->GetMinimum(“run”);
int maxRun = (int) t->GetMaximum(“run”);
int minCycle = (int) t->GetMinimum(“cycle”);
int maxCycle = (int) t->GetMaximum(“cycle”);
int i=0;
for (int iRun = minRun; iRun <= maxRun; ++iRun) {
for (int iCycle = minCycle; iCycle <= maxCycle; ++iCycle) {
int entry = t->GetEntryNumberWithIndex(iRun, iCycle);
if (entry < 0) continue;
table[i] = entry;
++i;
}
}
//loop branch by branch on the input Tree and fill the output Tree
TIter next(t->GetListOfBranches());
TBranch *bin, bout;
while ((bin = (TBranch)next())) {
bout = sortedTree->GetBranch(bin->GetName());
//cout << "processing branch: " << bin->GetName() << endl;
//load all baskets of this branch in memory (for performance)
bin->LoadBaskets();
//loop on entries and fill output Tree
for (int i=0; i< t->GetEntries(); ++i) {
int entry = table[i];
bin->GetEntry(entry);
bout->Fill();
}
bin->DropBaskets();
I was trying to use the CopyTree(“selection”) function to filter my tree. In this case, whenever it is called, a new copy of the tree is created in the file.
To avoid it, I do:
TFile fin("myfile", "READ");
TTree* t = (TTree*) fin.Get("mytree");
TFile fout("myoutfile", "RECREATE");
gROOT->cd(0); // Next objects will be read to memory
TTree* ct = t-CopyTree("selection");
fout.cd(0); // Next objects will be read to file
ct->Write(0,TObject::kWriteDelete);