TTree after SaveAs

What happens with a TTree created without a file after SaveAs() method is called?

Is it possible to recover the tree or the only way to continue is to reload it from the file?
As I understand, the problem is that after SaveAs is called, the file created by ROOT is closed.
The Print() method still shows the correct tree structure, only “All baskets in memory”
change to “File Size = [some_number is here]”
The Show() method gives error:
Error in TTree::Show(): Cannot read entry 0 (I/O error)

Does that mean that the branch data was removed from the memory? If not, is there a way to remedy the problem?


ROOT Version (e.g. 5.34/36) - have to stick with this to support Windows users of our package
Win7 MSVC2013


Hi @Andr,

Let me ask @pcanal, our I/O expert, to provide you with an answer.

Cheers,

Enric

Thank you Enric!

Andrey

Hi Andr,

Am I understanding correctly that you are attempting to fill a TTree ‘in-memory’, then want to take a snapshot, and continue to have all the data in memory? If so, why is that advantageous for you (instead of the usual: connect the TTree to file and have the date written automatically as you go …). (in other words, what is the bigger picture here).

Cheers,
Philippe.

Hello Philippe!

First of all, I have to say that I am using ROOT as a library inside a Qt c++ application (I start TApplication inside QApplication, update on root on timer, transfer mouse click to root canvas etc). See https://github.com/andrmor/ANTS2 for more details.

Currently I am working on a scripting module to give access to TTrees for JavaScript and Python scripts. I do have a method where a file is created behind the ttree, but in many situations a tree is used as a temporary container and the file is not needed. It also give less headache with managing the tree life (I could report problems in another post).

So I created a method which creates + writes to / reads from ttrees without the file behind. It works very well, but for completeness I would like to give a possibility to save that kind of trees.

The SaveAs method gives a simple way to do it. After the save the tree header is still readable, so I just thought it is a bit strange (not logical?) that the tree contents seems to be lost in memory. It seemed more logical that the content is still there, I just do not know how to restore the access.

Any help will be very appreciated!

Regards,
Andrey

Hi Andrey,

Currently SaveAs has a generic implementation which essentially does (for your case):

      TFile *local = TFile::Open(fname.Data(),"recreate");
      if (!local) return 0;
      nbytes = obj->Write();

and TTree::Write is designed to flush the basket to disk (and remove them from memory) … as this is the common case.

On the other hand in your use case, what you need is:

      TFile *local = TFile::Open(fname.Data(),"recreate");
      if (!local) return 0;
      TTree *newtree = tree->Clone(-1, "fast");

but this would lead to the serialization/deserialization of the content one more time.

Another alternative to ‘store’ the in-memory TTree into a TMemFile. So create it as:

TMemFile *memfile = new TMemFile(name);
TTree *tree  = new TTree(....);

or

TTree *tree  = new TTree(....);
...
TMemFile *memfile = new TMemFile(name);
tree->Write();

In the first case, the basket (except the last one) would be stored in memory in serialized and compressed form rather than serialized but uncompressed form.

In the second case, the compression would happen at the time of the Write.

Then after either of those, you can do:

      TFile *local = TFile::Open(fname.Data(),"recreate");
      if (!local) return 0;
      TTree *newtree = tree->Clone(-1, "fast");

and this will simply copy the compressed buffer from the TMemFile directly to disk.

Cheers,
Philippe.

Thank you Philippe for such a detailed answer!

All the possibilities you have described have their drawbacks, so I think that the “brute” approach is the less complex:
after the save, delete the tree and load one just saved. Then I do not increase the number of cases to handle,
and automatically treat that tree as one of the “loaded” type.

Regards,
Andrey

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