Re: [ROOT] Reading and cleaning of TClonesArray

From: Ruben Shahoian (Ruben.Shahoyan@cern.ch)
Date: Tue Nov 26 2002 - 21:05:14 MET


Thank you Rene,
I am using Delete() in many situations, so I would like to know all
restrictions. Did I understand your recipe correctly:
1) if the TClonesArray is read from the Tree, the user must free himself
the "dynamic" part of the objects in the TClonesArray and then call Clear()
2) in other situations one can use TClonesArray::Delete() ?

Regards,
	Ruben

On Tue, 26 Nov 2002, Rene Brun wrote:

> Hi Ruben,
> 
> When your TClonesArray contains dynamic structures (like TNamed),
> you must delete these dynamic structures before clearing
> the array at each entry. I give an example of what you can do
> below, still preserving some of the advantages of a TClonesArray.
> 
> Rene Brun
> 
> //_________________________________________________________
> void trrd()
> {
>   printf("Reading back the tree\n");
>   char name[100];
>   TClonesArray* fVTVerts = new TClonesArray("TNamed",10);
>   //
>   TFile* flin = new TFile("trout.root");
>   TTree *tree = (TTree*)flin->Get("tree");
>   TBranch* trbr = tree->GetBranch("mybr");
>   trbr->SetAddress(&fVTVerts);
>   //
>   int nev = tree->GetEntries();
>   int iv,nv;
>   for (int iev=0;iev<nev;iev++) {
>     trbr->GetEntry(iev);
>     nv = fVTVerts->GetEntriesFast();
>     printf("\n\nRead Event %d %d Old Vertices Are\n",iev,nv);
>     fVTVerts->Print();
>     printf("\nNow will call TClonesArray::Delete() and Create new
> Vertices\n");
>     for (iv=0;iv<nv;iv++)
> ((TNamed*)fVTVerts->At(iv))->SetNameTitle("","");
>     fVTVerts->Clear();
>     // Reanalyze event, creating new vertices
>     nv = gRandom->Integer(5)+1;
>     for (iv=0;iv<nv;iv++) {
>       sprintf(name,"New Vtx %d of Ev %d",iv,iev);
>       TNamed* vp = new ((*fVTVerts)[iv]) TNamed(name,name);
>     }
>     printf("\nUpdated Event: New Vertices Are:\n");
>     fVTVerts->Print();
>     for (iv=0;iv<nv;iv++)
> ((TNamed*)fVTVerts->At(iv))->SetNameTitle("","");
>     fVTVerts->Clear();
>   }
>   delete flin;
>   delete fVTVerts;
> }
> 
> 
> On Mon, 25 Nov 2002, Ruben Shahoyan wrote:
> 
> > Hello,
> > I have encontered the following problem:
> > I am reading from the tree an event, which among other branches has one
> > with TClonesArray of the vertices (objects which allocate the memory).
> > I need to reanalize the event, so I have to clean the loaded vertices and
> > create new ones. But if I call TClonesArray::Delete() to clean this array,
> > loading next event produces SegVol.
> > 
> > Below I show the simple macros demonstrating the problem. Does anybody 
> > know the solution?
> > 
> > Thanks in advance,
> > 	Ruben Shahoyan
> > 
> > 
> > //_____________________ Sample Macro________________________
> > void trwr(int nev);
> > void trrd();
> > 
> > void trtest(int nev=20) 
> > {
> >   // Step 1: Create tree, with the branch of TClonesArray of the objects
> >   // allocating memory
> >   trwr(nev);
> >   //
> >   // Step 2: Read the tree, trying to "modify" the TClonesArray
> >   trrd();
> > }
> > 
> > //_________________________________________________________
> > void trwr(int nev)
> > {
> >   printf("Generating the tree with %d events\n",nev);
> >   char name[100];
> >   Int_t bfsize=32000;
> >   Int_t split=2;
> >   TClonesArray* fVTVerts = new TClonesArray("TNamed",10);
> >   fVTVerts->SetOwner();
> >   //
> >   TFile* flout = new TFile("trout.root","RECREATE");
> >   TTree *tree = new TTree("tree","tree");
> >   tree->Branch("mybr","TClonesArray",&fVTVerts,bfsize,split);
> >   //
> >   for (int iev=0;iev<nev;iev++) {
> >     fVTVerts->Delete();
> >     int nv = gRandom->Integer(10)+1;
> >     for (int iv=0;iv<nv;iv++) {
> >       sprintf(name,"Vtx %d of Ev %d",iv,iev);
> >       TNamed* vp = new ((*fVTVerts)[iv]) TNamed(name,name);
> >     }
> >     tree->Fill();
> >   }
> >   tree->Write();
> >   delete tree;
> >   flout->Close();
> >   delete flout;
> >   delete fVTVerts;
> > }
> > 
> > //_________________________________________________________
> > void trrd()
> > {
> >   printf("Reading back the tree\n");
> >   char name[100];
> >   TClonesArray* fVTVerts = new TClonesArray("TNamed",10);
> >   fVTVerts->SetOwner();
> >   //
> >   TFile* flin = new TFile("trout.root");
> >   TTree *tree = (TTree*)flin->Get("tree");
> >   TBranch* trbr = tree->GetBranch("mybr");
> >   trbr->SetAddress(&fVTVerts);
> >   //
> >   int nev = tree->GetEntries();
> >   for (int iev=0;iev<nev;iev++) {
> >     trbr->GetEntry(iev);
> >     printf("\n\nRead Event %d %d\n Old Vertices Are",iev,fVTVerts->GetLast()+1);
> >     fVTVerts->Print();
> >     printf("\nNow will call TClonesArray::Delete() and Create new Vertices\n");
> >     //fVTVerts->Clear();  !! Works with Clear, but will lead to memory leak! 
> >     fVTVerts->Delete();
> >     // Reanalyze event, creating new vertices
> >     int nv = gRandom->Integer(5)+1;
> >     for (int iv=0;iv<nv;iv++) {
> >       sprintf(name,"New Vtx %d of Ev %d",iv,iev);
> >       TNamed* vp = new ((*fVTVerts)[iv]) TNamed(name,name);
> >     }
> >     printf("\nUpdated Event: New Vertices Are:\n");
> >     fVTVerts->Print();
> >     //
> >   }
> >   delete tree;
> >   flin->Close();
> >   delete flin;
> >   delete fVTVerts;
> > }
> > 
> > 
> 
> 



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:21 MET