Re: inheriting from TClonesArray

From: Rene Brun (Rene.Brun@cern.ch)
Date: Tue Jun 09 1998 - 10:42:01 MEST


Jiri,
There is nothing wrong in creating a class deriving from
TClonesArray. From your description below, I assume that you are
creating a TTree with one branch referencing one event object.
You must proceed like in $ROOTSYS/test/Event. Make sure that the
the TClonesArray is created only once. In our example,
we use a global pointer gTracks. In the Event constructor, we simply
set the pointer fTracks to point to gTracks.
It would be better to have a Run class with a member fTracks
and in the Event constructor to point to this object.

Rene Brun


> 
> Hello,
>         I've defined a class called Tracks which inherits from
> TClonesArray. It's a collection of Track objects and extends the
> functionality of TClonesArray by jet algorithms, display methods etc.
> In my Event class I have pointers to several Tracks objects. The event
> class constructor allocates every time new Tracks object via fTracks =
> new Tracks(); which is deleted in Event destructor by delete fTracks.
>         Everything seems to work fine when I create event object and
> add tracks to it. upon deletion of the event object also the Tracks
> object and the contents of the collection are destroyed. When I check
> in gObjectTable afterwards, there's nothing left from my
> Event/Tracks/Track objects.
>         The problem is that when I use tree->GetEvent() to read events
> back from a file, there's a memory leak which prevents me from
> analysing larger data volumes. there is one Tracks object per event
> left in the gObjectTable. When I replace pointer to Tracks object in
> the event class by pointer to TClonesArray I don't observe any memory
> deallocation problems so I guess the problem comes from my Tracks
> class.
>         I also tried a scenario similar to the example coming with
> Root - to call new Tracks() only first time when event object is
> created and call Delete method of TClonesArray when Track objects are
> not needed anymore but the behaviour is the same - again Tracks
> objects left.
>         Please my questions are whether it is ok to put derived
> objects from TClonesArray in a TTree and how should I write proper
> constructor/destructor for such a class.
> 
> thank you in advance for your help.
> 
>                 Jiri
> 
> ////////////////////////////////////////////////////////////
> class Tracks : public TClonesArray {
> private:
>   Int_t  fNtrack;
> 
> public:
>   Tracks();
>   Tracks(Int_t size);
>   ~Tracks();
>   void    AddTrack(Float_t x,Float_t y,Float_t z,Float_t e,Float_t m,Int_t ch);
>   Track*  Get(Int_t index);
>   void    Print() const;
> 
>   ClassDef(Tracks,1)
> };
> 
> ////////////////////////////////////////////////////////////
> Tracks::Tracks()
>   :TClonesArray("Track",32, kFALSE){
>     fNtrack = 0;
> }
> 
> Tracks::~Tracks(){
>   cout << "<T\n";
> }
> 
> void
> Tracks::AddTrack(Float_t x,Float_t y,Float_t z,Float_t e,Float_t m,Int_t ch){
>   Tracks &tracks = *this;
>   new(tracks[fNtrack++]) Track(x,y,z,e,m,ch);
> }
> 
> ////////////////////////////////////////////////////////////
> class Event : public TObject {
> 
> public:
>   Int_t          fNtrack;
>   EventHeader    fEvtHdr;
>   Tracks        *fTracks;
> 
> public:
>   Event();
>   ~Event();
>   void      Clear(Option_t *option ="");
>   void      SetHeader(Int_t i, Int_t run, Int_t date, Float_t bm);
>   void      AddTrack(Float_t x,Float_t y,Float_t z,Float_t e,Float_t m,Int_t ch);
>   EventHeader  *GetHeader() { return &fEvtHdr; }
>   Tracks       *GetTracks() { return fTracks; }
> 
>   ClassDef(Event,1)  //Event structure
> };



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:33 MET