Questions regarding TTree and their NameCycles

Hi All,

I have a series of questions regarding TTrees of the same name and different namecycles. I’d like to make sure I know what is going on because, even after several years of being a ROOTer, I still am unsure about this and haven’t been able to find it explained fully :confused:

I currently have a root file with two trees: myTree;1 and myTree;2. This file was created by a script which defined and wrote only one instance of the tree to the root file. Here is the code:

typedef struct {Float_t x,y,z;} POINT;

void ttreeNameCycles(){

  POINT point;
  TFile *file = new TFile("myTree.root","RECREATE");
  TTree *tree = new TTree("myTree","myTree");
  tree->Branch("point",&point,"x:y:z",10);

  TRandom3 rand(0);

  for (Int_t i=0; i<1000000; i++){
    point.x = i;
    point.y = rand.Uniform(0,1);
    point.z = rand.Uniform(0,1);
    tree->Fill();
  }

  tree->Write();
}

Here are my questions:

  1. My understanding of why I have two trees of the same name is the following. ROOT began by filling a tree called myTree;1. When that tree became larger than its buffer size it was written to the file and ROOT continued on writing to a tree called myTree;2. Is this correct?

  2. When I examine the two tree individually I find that myTree;1 contains 612246 entries and that myTree;2 contains the full 1000000 entries. And that the first 612246 entries of myTree;2 are identical to those in myTree;1. Is it always guaranteed that myTree;1 will be a subset of myTree;2?

  3. When I look at the file size of myTree.root I find that it is ~35MB. If I then open the root file and delete myTree;1 using TFile::Delete() I would expect the file size to be reduced. But this doesn’t seem to be the case! Why?

  4. When I want to read a tree from a file like this I find that retrieving the tree from the file via TFile::Get() returns to me a pointer to a tree that contains all the entries - 1000000 in this case. Presumably then ROOT is smart enough to know it should always pick the tree with the greatest namecycle? Is this the default behavior?

  5. If my understanding is all correct it really seems that a more intuitive behavior for writing the file would be to delete myTree;1 and leave me only with myTree;2. Why does this not happen? Why is myTree;1 still kept as a key in the final file?

My thanks for your answers and corrections!

Cheers,
Chris

1 Like

Hi,

You may want to re-read the User’s Guide chapter on I/O and in particular the discussion about ‘cycles’

Sorta … When the number of entries reached the one given by ‘AutoSave’, the meta-data is flushed to the disk. A the previous version is kept around in case the writing of the new fail (so that most of the data is still readable even in case of crash). The cycles are backups.

Yes. ;1 is an older snapshot of the meta data.

The delete only remove the meta data and not the data (as it might be associated with other cycles) and thus the amount freed is small. In addition, this size freed is likely to be in the middle of the file and thus the file can not be shrunk as shrinking it would requires moving the other part (and updating the meta data pointing to them).

Yes.

See the User’s Guide for a complete answer and my previous answer for the short version.

Cheers,
Philippe.

Answering to 5:

For deleting the previous cycle and just stay with the newest one, use instead:

tree->Write("",kWriteDelete);
1 Like