TChain problem with empty file

Hi,
I wrote a very simple function reading a number of files
with trees in and building a chain to create afterwards some
histos. It happens that because of problems some files do not
have the tree inside. When chain.Add is called, I get a long long list
of error messages (tree not found or something like that).
I tried to add checks on the existence of the file and on the
tree, but the macro as attached breaks after it finds the empty file.
If I declare the TTree pointer for testing the presence of the tree
outside the loop (and of course do not delete it inside),
I get always the same pointer, regardless of the existence of the tree.
Someone could please point at my mistake, if any (optimism as a must…)
Thanks a lot
comb.tar.gz (942 KB)

Sorry, in my message I forgot to quote: v3-10-01, compiled with
gcc 3.2 on rh 7.3.
Cheers,
Rosario

Hi,

In your code you have:

TTree *albero = (TTree *)gROOT->FindObject("BB_Sample"); .... delete albero;
Since you have a TChain object named 'BB_Sample", this IS the object retrieved by gROOT->FindObject(“BB_Sample”). In consequence the delete albero deletes an object on the stack (a sure fire for crashes) and then still tries to access it.
Instead you should do:

TTree *albero = (TTree *)provaop->Get("BB_Sample");
Also you do not need to delete the ‘albero’ object since it will be delete by

See the Object Ownership chapter in the Users Guide.

In addition, with ROOT 4.00/03 (or the head of the CVS repository after March 9, 2004. The TChain object are able to handle elegantly being added broken or empty files.

Cheers,
Philippe.

Hi Philippe,

While investigating a way to skip corrupted files in a TChain, I came across your post above. You say that empty and corrupted files are now (ROOT 4.00/3 and later) handled more elegantly. I still experience crashes when having a broken file in a chain. I saw that for the empty file, you have the following code in LoadTree():

if (fTree==0) {
      // Now that we do not check during the addition, we need to check here!
      Error("LoadTree","cannot find tree with name %s in file %s",
            element->GetName(),element->GetTitle());

      delete fFile; fFile = 0;

      // We do not return yet so that 'fEntries' can be updated with the
      // sum of the entries of all the other trees.
   }

While for the case of corrupted files, you have:

   fFile = TFile::Open(element->GetTitle());
   if (!fFile || fFile->IsZombie()) {
      delete fFile; fFile = 0;
      return -3;
   }

Could it be that this is why broken files are not skipped?? In fact, this ‘return -3’ in LoadTree(), puts the TChain in a funny state: if the second file is a corrupted file and one does TChain::GetFile() (for example) afterward reaching it, LoadTree(0) will be called, leading to a segvio, because fTreeNumber==0, but the file is no longer open.

Could you look into this? It’s probably possible to give the same behaviour for broken files as for empty files. It would be great if those files were just skipped (A warning is always printed by TFile).

Thanks,

Marco.

Hi Marco,

You proposal to fix this problem has been uploaded to the CVS repository.

Thanks,
Philippe.