Disk resident tree

Hi forum,
I am running over a lot of root files, which have a tree in them, and creating a new root file with a new tree. The code I use has 3 main parts, a BeginJob(), Event(), and EndJob(). In the BeginJob() I do:

FileOut = new TFile (fFileName,"RECREATE"); fTree= new TTree ("tree", "Tree"); fTree->Branch("Njets", &Njets, "Njets/I");

then in Event(), which runs over a single event(entry in tree), I fill the tree for each event

Njets = fJetBlock->NJets(); fTree->Fill();

and in EndJob()

FileOut->Write(); FileOut->Close();

Now, the tree is saved into the root file, but if I have a big number of events, like 4 million, then root crashes giving me std::bad_alloc(), which seem to imply that I ran out of memory. But isn’t the way I describe above writing the tree directly to file, and flushing the memory? If no, is there a way to flush memory after each event?
Thanks a lot!
artur.

I was going to post something similar to this as a new topic, but since you started… :smiley:

To get a disk-resident tree, you simply open a TFile (using “Recreate”) and then create your tree (just like you do).

What we have seen is that when root decides that the root file that the tree is set in, it opens another file.

So far, so good. But when we try to do a FileOut->Close();
it seg-faults. The problem seems to be that what ‘FileOut’ points to is no longer a valid file.

What we do to get around it is do a treePtr->GetCurrentFile()->cd(); treePtr->Write(); and deliberately not close the file. This works as long as the job finishes successfully, but can have issues if the job crashes after you have 'Write()'ed the tree.

Note that we also tried doing a

treePtr->GetCurrentFile()->Write()
But that crashes too.

To see symptoms of this yourself, simply use ‘treePtr->>SetMaxTreeSize()’ to something quite small and you can create a lot of root files quickly.

So, how are we supposed to be doing this?

Cheers,
Charles

p.s. At CDF, we are (stuck) using Root version 4.00.08.

Note that instead of

treePtr->GetCurrentFile()->cd(); treePtr->Write(); you can simply do

treePtr->AutoSave(); AutoSave will automatically write the tree header in the directory where
you have initially created the Tree and will restore the current directory where it was at the entry of AutoSave.

Rene

Hi Rene

[quote=“brun”]Note that instead of

treePtr->GetCurrentFile()->cd(); treePtr->Write(); you can simply do

treePtr->AutoSave(); AutoSave will automatically write the tree header in the directory where
you have initially created the Tree and will restore the current directory where it was at the entry of AutoSave.
[/quote]

Two questions:

  1. Is AutoSave() correctly implemented in Root 4.00.08?

  2. Does AutoSave() close the last file? How can we close the last file so that it is not corrupted if rest of the job crashes?

Cheers,
Charles

[quote]1) Is AutoSave() correctly implemented in Root 4.00.08?
[/quote]
I hope so !

[quote]2) Does AutoSave() close the last file? How can we close the last file so that it is not corrupted if rest of the job crashes?
[/quote]
What do you mean by “last file”? Did you SetMaxTreeSize such that
you have Tree spans several output files? If this is the case, read
the “IMPORTANT NOTE” at
root.cern.ch/root/htmldoc/TTree. … ChangeFile

Rene

That’s exactly what I meant. I’ve tried the below code (from your above note) in 4.00.08 and it still crashes on I do the Close(). I’ll see if I can come up with a short script to show the problem.

  file = T->GetCurrentFile(); //to get the pointer to the current file
  file->Write();
  file->Close();

Could you send the shortest possible setup reproducing this problem?

Rene