"R__unzip: error in header" in ROOT 5.14-00e

Hi.

I’m using ROOT 5.14-00e to fill a tree, then using a macro based on the same ROOT version to read it out. I see no errors in the log for the job which fills the tree, but I can’t even open the tree as seen below:

root [2] TFile a(“temp.root”)
root [3] a.ls()
TFile** temp.root
TFile* temp.root
KEY: TTree fitSample33-2;1 fitSample33-2
root [4] t = (TTree*)a.Get(“fitSample33-2”)
R__unzip: error in header
(class TTree*)0x0

In general, I’m creating ROOT files with about 10 trees, and this problem affects only 3 of the trees…the first 3 written to the file. The other trees are fine. I’ve regenerated the filesnumerous times, and the problem is reproduced.

I’ve seen postings relating this message to I/O problems, including a bug
in ROOT 3.04. But I’m not sure what to do with it here…

-Jeff

Could you post the output of the following session

root [1] TFile a("temp.root") root[2] a.Map(); >a.map root [3] gDebug=2; root [4] t = (TTree*)a.Get("fitSample33-2") ; >a.debug
and post as attachments the files a.map and a.debug

Rene

Hi Rene,

I’ve attached the file a.map.gz. The content of a.debug is:

TKey Reading 158313 bytes at address 129489111

The output of the session is below, using the “real” filename:

root [0] TFile a(“ntuples/fitData/ERHO/PidLHElectrons.piLHLoose.root”)
root [1] a.Map(); >a.map
root [1] gDebug = 2
(const int)2
root [2] t = (TTree*)a.Get(“fitSample33-2”); > a.debug
R__unzip: error in header
root [3]
a.map.gz (400 KB)

You forgot to add the a.debug file.

Rene

As I said above, the content of “a.debug” is simple:

TKey Reading 158313 bytes at address 129489111

In the previous post, I was having trouble attaching the debug file. Now I see that the attached file must be named with one of the accepted extensions.
a.debug.txt (47 Bytes)

It looks like you have written the TTree headers in a file different of the one where the baskets are written.
In the case of your file, you have 3 TTree headers at the end of the file

20070913/021740 At:470317240 N=439851 TTree CX = 2.49 20070913/021740 At:470757091 N=92059 TTree CX = 2.25 20070913/021740 At:470849150 N=334020 TTree CX = 2.05
However the TTree that you are trying to read is at address 129489111.
If you look at your a.map file, there is a TBasket at this address, not a TTree header. You should check your code writing the TTree headers to the file. I suspect that you forgot to cd to the rigth file before writing these headers.

Rene

Hi Rene,

I’ve narrowed down the problem to a few lines of code but I don’t understand why it’s a problem.

The code that makes and fills my trees looks basically like this:

//clean out previously existing file, if any
TFile *filePrepare = new TFile(fileName,“RECREATE”);
filePrepare->Close();
delete filePrepare;
filePrepare = 0;

func(mode1,fileName);
func(mode2,fileName);
func(mode3,fileName);
etc. etc.

“func” is a function which opens up “fileName” in UPDATE mode, writes a few trees, and closes the file.

When I include the first four lines, which are there to avoid having to manually delete any pre-existing file with the name “fileName”, the file headers get all messed up, as in the previous posts. When I remove those four lines and delete the old file manually, everything works fine. What is wrong with this method of cleaning out the old file?

-Jeff

I need the shortest possible running script/program reproducing the problem.

Rene

Here’s a simple macro which displays my problem. The problem seems to be in the TFile::Delete call in ‘func’. If ‘func’ is called more than once, this Delete call seems to mess up the TFile headers. If I remove the call to TFile::Delete in ‘func’, everything is OK.

There’s more. If I manually delete temp.root first and comment out the first four lines of ‘test’, the TFile headers are OK even when I call TFile::Delete multiple times.

-Jeff

void test(){

// delete old file, if any

TFile *f = new TFile(“temp.root”,“RECREATE”);
f->Close();
delete f;
f = 0;

//fill file with dummy trees

func(“tree1”);
func(“tree2”);

}

void func(char * name) {

TFile *g = new TFile(“temp.root”,“UPDATE”);

// delete any pre-existing trees of the same name

char nameCycle[100];
sprintf(nameCycle,"%s;*",name);
g->Delete(nameCycle);

TTree *tree1 = new TTree(name,name);

Float_t flt = 1;
tree1->Branch(“branch”,&flt,“temp/F”);

for(int i; i < 500; i++) {
tree1->Fill();
}

g->Write();
tree1->Reset();
delete tree1;
tree1 = 0;

g->Close();
delete g;
g = 0;

}

The problem seems to happen with the following sequence
-create an empty file
-delete file object in memory
-open file again in update mode
-call TFile::Delete
-write something, close, etc

We will investigate this problem (once Philippe will be back).
Meanwhile, I suggest to simplify your program as illustrated below

Rene

[code]void test(){
//fill file with dummy trees

func(“tree1”);
func(“tree2”);
}

void func(char * name) {

//file is created if it does not exist
TFile *g = new TFile(“temp.root”,“UPDATE”);

// delete any pre-existing trees of the same name

char nameCycle[100];
sprintf(nameCycle,"%s;*",name);
g->Delete(nameCycle);

TTree *tree1 = new TTree(name,name);

Float_t flt = 1;
tree1->Branch(“branch”,&flt,“temp/F”);

for(int i; i < 500; i++) {
tree1->Fill();
}

tree1->Write();
delete g;
}[/code]

Rene,

Your sequence will reproduce the problem:

[quote]
The problem seems to happen with the following sequence
-create an empty file
-delete file object in memory
-open file again in update mode
-call TFile::Delete
-write something, close, etc [/quote]

However, your simplified code omits the initial creation of the empty ROOT file. Without this call, I don’t think the problem occurs. And this is a necessary step for my code.

You do not need the initial call to create your empty file. When using the “update” option
it behaves like “new” or “recreate”. See my code where I simplified your logic.

Rene

I use the initial call to delete (if necessary) a previously existing file of the same name. This is necessary because my TTree objects are very large and calls to TFile::Delete do not actually reduce the size of the ROOT file. Thus, if I remake these trees more than 2-3 times without deleting and remaking the ROOT file, the file reaches the 2GB limit.

OK but the clean solution is to store one Tree per file and overwrite the previous file when you recreate the tree.

Rene

Hi,

The problem has been fixed in the svn trunk (It was an inability to update correctly an empty file).

Cheers,
Philippe