Re: [ROOT] TChain, TClonesArray and inheritance

From: Rene Brun (Rene.Brun@cern.ch)
Date: Wed Jan 09 2002 - 11:27:57 MET


Hi Benoit,

The main problem in your test was that you delete the TClonesArray
in the Gentest destructor and you do not reset the static gtca.

I have recoded/simplified your example. See attachement

untar test.tar.gz
run the 3 lines script go
root -b -q test.C
root macro.C

Rene Brun

Benoit Revenu wrote:
> 
> Hi !
> 
> I meet some problems when I use a TClonesArray made upon a derived class.
> 
> These are the different step I follow :
> ---------------------------------------
> 1. create an instance of the class Test, derived from GenTest (derived
>    from TObject). files class.h and class.cc
> 2. Construct a TClonesArray based on this instance of Test (class.cc)
> 3. Create a TTree and one branch based on an instance of Test (test.cc)
> 4. make a test program run and fill the tree, then writing a root file
>    (test.cc)
> 5. I launch root interactive and I use a TChain to read the TTree
>    contained in the root file (macro.cc)
> 6. make some plots of variable contained in the Test, itself contained in
>    the TClonesArray ====> NO PROBLEM !
> 7. just add another root file of the same format and same data to the
>    existing TChain (->Add("file.root")) and impossible to make plots of
>    the variables contained in the TClonesArray.
> 
> This problem seems to exist only with this derived class. If the class
> Test only derive from TObject, then there are no problems.
> 
>         Any idea ???
> 
> ---------------------------------------------------------------------------
> these are the files :
> ---------------------
> ##############################
> #        class.h             #
> ##############################
> #ifndef CLASSH
> #define CLASSH
> 
> #include "TClonesArray.h"
> #include <iostream>
> 
> class Truc : public TObject
> {
>  public:
>   Truc(double b=-1){a=b;}
>   ~Truc(){}
>   double a;
>   ClassDef(Truc,1)
> };
> 
> class GenTest : public TObject
> {
>  public:
>   GenTest(unsigned int=0);
>   virtual ~GenTest();
>   TClonesArray *tca;
>   Int_t Nstat;
>   Int_t totNstat;
>   void AddTruc(double);
>   void Clear();
>   ClassDef(GenTest,1)
> };
> 
> class Test : public GenTest
> {
>  public:
>   Test();
>   virtual ~Test();
>   static TClonesArray *gtca;
>   ClassDef(Test,1)
> };
> 
> #endif
> 
> #############################
> #       class.cc            #
> #############################
> #include "class.h"
> 
> ClassImp(GenTest)
> ClassImp(Test)
> ClassImp(Truc)
> 
> GenTest::GenTest(unsigned int address)
> {
>   if( address == 0x0 )
>     {
>       tca = new TClonesArray("Truc",10);
>     }
>   Nstat = 0;
>   totNstat = 0;
> }
> 
> GenTest::~GenTest()
> {
>   cout << "~GenTest()" << endl;
>   Clear();
>   if( tca != NULL ) delete tca;
> }
> 
> void GenTest::AddTruc(double a)
> {
>   TClonesArray &truc = *tca;
>   new(truc[Nstat++]) Truc(a);
>   totNstat++;
> }
> 
> void GenTest::Clear()
> {
>   tca->Clear();
>   Nstat = 0;
> }
> 
> /******** Test *********/
> 
> TClonesArray * Test::gtca = 0x0;
> 
> Test::Test() : GenTest((unsigned int)gtca)
> {
>   gtca = tca;
> }
> 
> Test::~Test()
> {
>   gtca = 0x0;
> }
> 
> #################################
> #       classLinkDef.h          #
> #################################
> #ifdef __CINT__
> 
> #pragma link off all globals;
> #pragma link off all classes;
> #pragma link off all functions;
> #pragma link off all typedef;
> 
> #pragma link C++ class Truc;
> #pragma link C++ class GenTest;
> #pragma link C++ class Test;
> 
> #endif
> 
> #################################
> #       test.cc (main)          #
> #################################
> #include <fstream>
> #include <math.h>
> 
> using namespace std;
> 
> #include "TFile.h"
> #include "TTree.h"
> #include "TROOT.h"
> #include "TCanvas.h"
> #include "TApplication.h"
> #include "TGraph.h"
> #include "class.h"
> 
> TROOT root("Example","Example of data reading for the Auger experiment");
> Test * pevt;
> 
> int main (int argc, char *argv[])
> {
>   TApplication theApp ( "App", NULL, 0 );
>   gROOT->Reset( );
> 
>   TFile * outfile = new TFile( "/tmp/outfile.root", "RECREATE", "test" );
>   TTree * resultP = new TTree( "ResultP", "EAS parameters" );
> 
>   pevt = new Test();
>   int bufsize = 10000;
>   Int_t split = 3;
>   resultP->Branch( "PhysEvents", "Test", &pevt, bufsize, split );
>   resultP->GetBranch("PhysEvents")->SetAddress(&pevt);
> 
>   for( int i=0;i<10000;i++ )
>     {
>       pevt->AddTruc((double)i);
>       resultP->Fill();
>       pevt->Clear();
>     }
> 
>   outfile->Write();
>   outfile->Print();
>   outfile->Map();
>   outfile->Close();
>   return 0;
> }
> 
> ############################
> #       Makefile           #
> ############################
> ROOTDIR=${ROOTSYS}/
> ROOTBIN=${ROOTDIR}bin/
> ROOTLIB=${ROOTDIR}lib/
> 
> TMP=/opt/
> OBJSDIR=${TMP}Objs/
> LIBSDIR=${TMP}Libs/
> MOBJS=${OBJSDIR}classDict.o ${OBJSDIR}class.o
> CFLAGS=`${ROOTBIN}root-config --cflags` -Wall -DDPA -g
> LIBS=`${ROOTBIN}root-config --libs` -Wl,-rpath ${ROOTLIB}
> EXE=./test
> 
> all: ${EXE}
> 
> ${OBJSDIR}%.o: %.cc
>   ${CXX} -c $< -o $@ ${CFLAGS}
> 
> classDict.cc: class.h classLinkDef.h
>   ${ROOTBIN}rootcint -f classDict.cc -c class.h classLinkDef.h
> 
> ${LIBSDIR}libtest.so: ${MOBJS}
>   g++ -shared -o $@ ${MOBJS}
> 
> clean:
>   rm -f ${OBJSDIR}*.o ${EXE}
>   rm -f ${LIBSDIR}*.a ${LIBSDIR}*.so
>   rm -f classDict.* core
> 
> test: ${LIBSDIR}libtest.so ${OBJSDIR}test.o
>   ${CXX} ${CFLAGS} ${OBJS} ${OBJSDIR}test.o ${LIBS} -L${LIBSDIR} -ltest -o
> $@
> 
> and finally the macro:
> #############################
> #        macro.cc           #
> #############################
> {
> gROOT->Reset();
> gSystem->Load("/opt/Libs/libtest.so");
> 
> TCanvas * c1 = new TCanvas;
> TPad * pad = new TPad("pad","",0,0,1,1) ;
> 
> TChain * chainp = new TChain("ResultP");
> 
> chainp->Add("/tmp/outfile.root");
> chainp->Draw("a"); // OK AT THIS POINT
> 
> chainp->Add("/tmp/outfile.root");
> chainp->Draw("a"); // GIVES *** Break *** segmentation violation in root
> }



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