Delete TObject in TFile and use the freed space


I have several TTrees in a TFile. I wish to “reprocess” the data, that is to say, replace a TTree with a new one. Well, I could just create a new TFile, clone the TTrees I want to keep and compute the new TTree.
However, that proves to be lengthy in the case where I have several large TTrees to clone.
From the documentation, I understand that I could delete the TTree from the TFile and free the corresponding space, which could be used by ROOT to save the newly computer TTree.

I implemented something naive like:

TFile fin("myfile.root","update");
TIter nextkey(fin.GetListOfKeys());
TKey *key=0;
while ((key = (TKey*)nextkey())) {
    string kname=key->GetName();
    if (kname=="subtract"){
TTree* sub=new TTree("subtract","pedestal subtracted data");
// Fill the TTree

However, the delete function prints out a very small number for nbytes:
Deleting key: subtract at address 7590310232, nbytes = 27096
knowing that the TTree size is rather of the order of Gbytes.
The total size of the TFile keeps increase at the same pace as before for each reprocessing.

What am I missing ?


ROOT Version : v6.12.06
Platform, compiler (fedora 27, gcc 7.3.1):


it is in general good practice to re-create files when processing data, for example after calibration.
I understand that the issue in your case is to carry over the datasets you do not manipulate. For these, TTree “fast cloning” should be the solution:

   TFile myfile ("small.root","recreate");
   oldtree.CloneTree(-1, "fast");

This procedure does not decompress/deserialise/serialise/compress anything, just copies bytes.
If the procedure of manipulating the data could also use a speedup, you can resort to the recommended data processing tool, TDataFrame which allows you to express your operations and parallelise transparently the processing using all of your cores.


thanks for your reply. Using “fast” options I gain a factor 300 (!!) in processing time while copying TTrees. Good!

Yes, recreating files when reprocessing is the best practice and that is what I am doing. But still, I am curious to know why my above example does not work. Is it possible to delete a TTree from a TFile and free that space to save in a newly computed TTree ?

Thanks for pointing this to me. I missed it. Very instructive !
In short, for people reading this post, the ‘deletion’ must be done from the TTree , and not from the key (so that the space occupied by the baskets (data) in the file is also reclaimed).

TTree* t = (TTree*)fin.Get("subtract");
t->Delete("all");//Delete key, TTree and all dependant TBaskets

instead of


in the above-mentioned code.

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