[ROOT] Empty TClonesArrays in trees

From: Fred Gray (fegray@npl.uiuc.edu)
Date: Sat Jan 27 2001 - 21:12:22 MET


Hi, fellow ROOTers,

The macros below are a simplified testcase representing a problem that has
made some real trouble for our group lately.

The record() macro generates a file containing a tree with one branch, 
a TClonesArray of TLine objects.  The arrays are of varying length, and the
length in each entry is printed out as the tree is written.  The play() macro
reads the file back in, printing out the length of the array in each entry.
In principle, the two counts ought to agree.  In fact, they don't:

In record():
1 12 5 1 2 0 10 3 3 15 4 2 7 0 0 9 5 5 17 2

In play():
1 12 5 1 2 2 10 3 3 15 4 2 7 7 7 9 5 5 17 2

For entries where the initial length was nonzero, things are fine.  However,
notice that, wherever the initial length was zero, the length played back is
equal to the length in the previous entry.  In our real application, you can
also see that the content of the array is the same as in the previous entry,
so this can lead to multiple inclusion of a set of events.

The problem occurs with (at least) ROOT versions 2.23/12 and 2.25/03.  I 
haven't tried the 3.0 series, but I would much prefer to make this work with a 
stable version since we're about to begin a long event processing run.

Am I doing something fundamentally wrong here?  Otherwise, does anyone know
of a good solution/workaround?

Thank you all very much for your help,

-- Fred Gray

record()
{
  // write file
  TFile *outFile = new TFile("testclones.root", "RECREATE");
  tree = new TTree("tree", "tree", 16*1024*1024);
  TClonesArray *array = new TClonesArray("TLine", 128);
  tree->Branch("b", &array, 1024, 1);

  TRandom *random = new TRandom3(1234);

  for(Int_t i = 0; i < 20; i++)
  { 
    Int_t numHits = random->Gaus(5,5);
    if(numHits < 0)
    {
      numHits = 0;
    }

    array->Clear();
    for(Int_t j = 0; j < numHits; j++)
    {
      TLine *line = new TLine(1,2,3,4);
      new((*array)[j]) TLine(*line);
      delete line;
    }
    printf("%d ", numHits);
    tree->Fill();
  }
  tree->Write();
  outFile->Write();
  outFile->Close();
  delete outFile;
  printf("\n");
}

play()
{
  // read it back
  TFile *inFile = new TFile("testclones.root");
  TTree *treeIn = inFile->Get("tree");
  TClonesArray *arrayIn = new TClonesArray("TLine", 128);

  treeIn->SetBranchAddress("b", &arrayIn);
  Int_t numEntries = tree->GetEntries();
  printf("numEntries = %d\n", numEntries);
  for(Int_t i = 0; i < numEntries; i++)
  {
    treeIn->GetEntry(i);
    printf("%d ", arrayIn->GetLast() + 1);
  }
  printf("\n");
}



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:34 MET