Saving TTree as class member leads to I/O error

,

Hi there

I’m getting I/O errors and invalid data when I try saving the clone of a tree as a class member to a new ROOT file.

I have a DAQ system where I fill a tree stored in a temporary file (don’t want to store it in memory and want to enable online analysis, therefore using ‘tree->AutoSave(“SaveSelf”)’ from time to time). After the acquisition, I would like to save the tree in the final file, embedded in a storage class. Later on, when I read the tree via the storage class from the final file, I get I/O errors.

The attached minimal example inspired from TTree as member variable shows the error on my ROOT v6-28-04 installation on RHEL 7:

.L breakingExample.C++
breakingExampleWrite();
breakingExampleRead();

breakingExample.C (1.6 KB)

Any ideas? Many thanks for your help!

Cheers,
Dominik

What kind of errors do you get? Maybe @pcanal can help?

******************************************************************************
*Tree    :tree      : tree                                                   *
*Entries : 10000000 : Total =       160004375 bytes  File  Size =   59685844 *
*        :          : Tree compression factor =   2.07                       *
******************************************************************************
*Branch  :Time                                                               *
*Entries : 10000000 : BranchElement (see below)                              *
*............................................................................*
*Br    0 :fSec      : Int_t                                                  *
*Entries : 10000000 : Total  Size=   40001093 bytes  File Size  =     150123 *
*Baskets :        6 : Basket Size=   20556843 bytes  Compression= 205.40     *
*............................................................................*
*Br    1 :fNanoSec  : Int_t                                                  *
*Entries : 10000000 : Total  Size=   40001141 bytes  File Size  =   13449913 *
*Baskets :        6 : Basket Size=   20556843 bytes  Compression=   2.29     *
*............................................................................*
*Br    2 :Value     : Value/D                                                *
*Entries : 10000000 : Total  Size=   80001185 bytes  File Size  =   46085808 *
*Baskets :        7 : Basket Size=   20556843 bytes  Compression=   1.34     *
*............................................................................*
Error in <TTree::Show()>: Cannot read entry 22 (I/O error)
************************************************
*    Row   * Time.fSec * Time.fNan * Value.Val *
************************************************
*        0 * 1.696e+09 *   5699000 *         0 *
*        1 * 1.696e+09 *   5699000 *         0 *
*        2 * 1.696e+09 *   5699000 *         0 *
*        3 * 1.696e+09 *   5699000 *         0 *
*        4 * 1.696e+09 *   5699000 *         0 *
*        5 * 1.696e+09 *   5699000 *         0 *
*        6 * 1.696e+09 *   5699000 *         0 *
*        7 * 1.696e+09 *   5699000 *         0 *
*        8 * 1.696e+09 *   5699000 *         0 *
*        9 * 1.696e+09 *   5699000 *         0 *

etc.

Hi @pcanal, would be great if you could have a look at this! Many thanks!

When reading a TTree indirectly from a file (your case), you need to reconnect the TTree to the file explicitly:

    auto stor = (storage*)file->Get("storage");
    stor->tree->SetDirectory(file);

You can also automate this behavior by extending the storage class by adding the function

  void DirectoryAutoAdd(TDirectory *dir) {
     if (tree)
       tree->SetDirectory(dir);
  }

which will be automatically called by TFile when reading object of the storage type.

Great, it’s working, thanks a lot!

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