Re: [ROOT] TChain, TClonesArray and inheritance

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


As usual, I forgot the attachement. Here it is

Rene Brun

Rene Brun wrote:
> 
> 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