[ROOT] TChain, TClonesArray and inheritance

From: Benoit Revenu (revenu@cdf.in2p3.fr)
Date: Mon Jan 07 2002 - 11:03:45 MET


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