Root file size growing exponentially using TClonesArrays

Hi,
I’m using TClonesArrays to hold three different classes I’ve made (one each for electrons, muons, and jets) that derive from TObject. I’ve noticed something very interesting. The size of the root file is growing exponentially with the number of entries I’m putting in the root file (I’ve also noticed it takes longer and longer for each 100 events as well). The only difference between the files below is how many “events” they’ve each got.

cplager@fcdflnx4> ll
total 671588
-rw-r--r--    1 cplager  cdf         387576 Apr 19 15:33 0100.root
-rw-r--r--    1 cplager  cdf       14942304 Apr 19 15:28 0500.root
-rw-r--r--    1 cplager  cdf       72251801 Apr 19 15:35 1000.root
-rw-r--r--    1 cplager  cdf      206386175 Apr 19 15:40 1500.root
-rw-r--r--    1 cplager  cdf      393727724 Apr 19 15:26 2000.root

I’ve checked and the later events have the same numbers of electrons, muons, and jets as the earlier events. The three classes I’ve created contain no dynamically allocated memory and are of constant size.

So, I must be doing something stupid with the TClonesArrays (right?). Here’s (basically) what I’m doing:

void TopFCNC::Loop(Int_t numWanted, bool debug)
{
   // random variables defined here


   // TCloneArrays
   TClonesArray *elecTcaPtr = new TClonesArray("CLPElectron", 10);
   TClonesArray *muonTcaPtr = new TClonesArray("CLPMuon", 10);
   TClonesArray *jetTcaPtr  = new TClonesArray("CLPJet", 30);
   TClonesArray &elecTca = *elecTcaPtr;
   TClonesArray &muonTca = *muonTcaPtr;
   TClonesArray &jetTca  = *jetTcaPtr;
   elecTca.BypassStreamer(true);
   muonTca.BypassStreamer(true);
   jetTca.BypassStreamer(true);

   // Various counters
   Int_t runNum;    
   Int_t eventNum;  
   Int_t numNTelecs;
   Int_t numNTmuons;
   Int_t numNTjets; 

   // open file for output
   TFile file ("/cdf/scratch/cplager/fcnc/skim.root", "RECREATE");

   // TCloneArrays
   TClonesArray *elecTcaPtr = new TClonesArray("CLPElectron", 10);
   TClonesArray *muonTcaPtr = new TClonesArray("CLPMuon", 10);
   TClonesArray *jetTcaPtr  = new TClonesArray("CLPJet", 30);
   TClonesArray &elecTca = *elecTcaPtr;
   TClonesArray &muonTca = *muonTcaPtr;
   TClonesArray &jetTca  = *jetTcaPtr;
   elecTca.BypassStreamer(true);
   muonTca.BypassStreamer(true);
   jetTca.BypassStreamer(true);

   // Various counters
   Int_t runNum;    
   Int_t eventNum;  
   Int_t numNTelecs;
   Int_t numNTmuons;
   Int_t numNTjets; 

   // open file for output
   TFile file ("/cdf/scratch/cplager/fcnc/skim.root", "RECREATE");

   // setup the tree
   TTree tree ("CLPTree", "CLPClasses Skim");
   // counters
   tree.Branch ("runNum"    , &runNum    , "runNum/I");
   tree.Branch ("eventNum"  , &eventNum  , "eventNum/I");
   tree.Branch ("numNTelecs", &numNTelecs, "numNTelecs/I");
   tree.Branch ("numNTmuons", &numNTmuons, "numNTmuons/I");
   tree.Branch ("numNTjets ", &numNTjets , "numNTjets/I");
   // TCAs
   tree.Branch ("electrons", &elecTcaPtr);
   tree.Branch ("muons",     &muonTcaPtr);
   tree.Branch ("jets",      &jetTcaPtr);

   for (Int_t entryIndex=0; entryIndex < nentries; ++entryIndex) 
   {
      // magically fill std::vectors of electrons, muons, and jets

      // copy vectors to TCAs
      // Electrons
      unsigned int size = elecList.size();
      elecTca.Clear();
      for (unsigned loop = 0; loop < size; ++loop)
      {
         new (elecTca[loop]) CLPElectron( elecList[loop] );
      } // for loop

      // Muons
      size = muonList.size();
      muonTca.Clear();
      for (unsigned loop = 0; loop < size; ++loop)
      {
         new (muonTca[loop]) CLPMuon( muonList[loop] );
      } // for loop

      // Jets
      size = jetList.size();
      jetTca.Clear();
      for (unsigned loop = 0; loop < size; ++loop)
      {
         new (jetTca[loop]) CLPJet( jetList[loop] );
      } // for loop
      elecTca.Compress();
      muonTca.Compress();
      jetTca.Compress();
      tree.Fill();
   } // for entryIndex
   file.Write();
}

I tried telling to not write the streamers and to compress before writing. Neither of these seemed to have much of an effect.

Because of contraints, I’m using Root Version 3.05/07 21 September 2003. I may be able to use Root Version 4.00/08 1 December 2004 if forced, but it would be a hard sell (to others), so I’d prefer not to have to change. Neither of these (as far as I remember) let me write out std::vectors directly.

I’m not particularly attached to TClonesArrays, except that I thought they were the right tool for the job.

Clearly, this exponential growth is going to become a problem quickly. Am I (hopefully) missing something? Is there some other container I should be using? Any other suggestions?

Cheers,
    Charles

What I didn’t mention (or realize) is that I wasn’t resetting the jets vector, so it was just growing and growing. :blush: So the TClonesArray was doing the right thing. Ugh. ](*,)

Charles