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