Problem using TTree::CloneTree

Hi,

One of our applications was exhibiting a bad allocation error when attempting a TTree::CloneTree(0) call on a relatively simple ntuple. It seems I can reproduce this interactively, using ROOT v5.18.00b. The file in question was generated with ROOT v5.16.00 and is the result of a filtering job. I am inquiring to find out more details of how this file was generated by one of our collaborators… however the file is available here:
ftp://ftp-glast.slac.stanford.edu/glast … merit.root

Interestingly, if I omit the t->GetEvent(0) line, the TTree::CloneTree(0) call succeeds. Am I triggering this behavior with my call to GetEvent without setting up any branch pointers? Or is that just coincidence?


  •                                     *
    
  •    W E L C O M E  to  R O O T       *
    
  •                                     *
    
  • Version 5.18/00b 10 March 2008 *
  •                                     *
    
  • You are welcome to visit our Web site *
  •      [root.cern.ch](http://root.cern.ch)            *
    
  •                                     *
    

ROOT 5.18/00b (branches/v5-18-00-patches@22563, Mar 28 2008, 13:51:00 on win32)

CINT/ROOT C/C++ Interpreter version 5.16.29, Jan 08, 2008
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] TFile *f = new TFile(“Skimmer_merit.root”)
root [1] TTree t = (TTree)f->Get(“MeritTuple”)
root [2] t->GetEvent(0)
(Int_t)(2020)
root [3] TFile *outFile = new TFile(“test.root”,“RECREATE”)
root [4] TTree *t2 = t->CloneTree(0)
Fatal in TStorage::ReAllocChar: storage exhausted
aborting

==========================================
=============== STACKTRACE ===============

================ Thread 0 ================
ntdll!KiFastSystemCallRet()
kernel32!WaitForSingleObject()
libCore!TWinNTSystem::DispatchOneEvent()

================ Thread 1 ================
libCore!DefaultErrorHandler()

================ Thread 2 ================
ntdll!KiFastSystemCallRet()
kernel32!Sleep()
libCore!TWinNTSystem::TimerThread()

================ Thread 3 ================
ntdll!KiFastSystemCallRet()
libCore!`anonymous namespace’::GetProgramCounter()
0xffffffffff006aec ??

==========================================
============= END STACKTRACE =============

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application’s support team for more information.

Thanks,
Heather

Heather,

I cannot reproduce your problem and no way to transfer your 1.5GB file from my place. Could you post a much smaller file (up to a few MBytes) reproducing the problem?

Rene

Hi Heather,

Your TTree has 482 branches each with a 1Mb TBuffer.

When you first load the tree, the memory use is 4821Mb.
When you do GetEntry(0) this load the ‘first’ buffer in addition to the last one, so you need 2
4821Mb.
When you do the CloneTree, you need another 482
1Mb.
So you are close to 1.5Gb which maybe above the limit set by your os/shell.

Cheers,
Philippe.

Hi Philippe,

Thanks - yikes - well that explains a lot :slight_smile:

Take care,
Heather

Hi,

So, once I have a file which large basket sizes, is there a way to recover? I attempted to open the file in UPDATE mode, and reset the branch basket sizes via SetBasketSize and re-write the file. Looking at TTree::Print, it appears the basket sizes have been reset, however, the same experiment of opening the file, grabbing the TTree, GetEvent and then CloneTree( 0 ) fails in the same fashion.

Is there a way to adjust the file to really use a smaller buffer size?

Thanks,
Heather

Hi Heather,

Not really … yet (see a related request at savannah.cern.ch/bugs/?36270).

In order for the new ‘size’ to be use, you would need to fill the TTree until the basket are full (are thus smaller are creating for the new entries).

You can also attempt to clone the TTree into a new TTree will smaller buffers (on a machine with enough memory and/or a high enough ulimit).

Cheers,
Philippe.