Re: [ROOT] Problem using new Branch() with TString?

From: Rene Brun (Rene.Brun@cern.ch)
Date: Tue Aug 14 2001 - 21:55:28 MEST


Hi Christian,

The correct output of your test program should be:
Filling tree
******************************************************************************
*Tree    :stuff     : MyClass entries
*
*Entries :       10 : Total =               0 bytes  File  Size =
0 *
*        :          : Tree compression factor =   1.00
*
******************************************************************************
*Branch  :MyClass
*
*Entries :       10 : BranchElement (see below)
*
*............................................................................*
*Br    0 :TObject   :
*
*Entries :       10 : Total  Size=          0 bytes  File Size  =
0 *
*Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
*
*............................................................................*
*Br    1 :fA        :
*
*Entries :       10 : Total  Size=          0 bytes  File Size  =
0 *
*Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
*
*............................................................................*
*Br    2 :fS        :
*
*Entries :       10 : Total  Size=          0 bytes  File Size  =
0 *
*Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
*
*............................................................................*
Reading tree
0: size = 1 aap
1: size = 2 aap
2: size = 3 aap
3: size = 4 aap
4: size = 5 aap
5: size = 6 aap
6: size = 7 aap
7: size = 8 aap
8: size = 9 aap
9: size = 10 aap

In version 3, TArray objects are not split (does not make too much sense).
Same for TString objects.

Could you start from the CVS version? I fixed a problem connected
with TArray objects in split mode a few weeks ago.

Rene Brun

On Tue, 14 Aug 2001, cstrato@EUnet.at wrote:

> Dear Rene
> 
> About 2 months ago I reported a problem that I have with the new
> Tree::Branch() function, and you asked me to supply a democode.
> See roottalk and followups:
>     http://root.cern.ch/root/roottalk/roottalk01/2035.html
> 
> In a reply to me Eddy Offermann was so kind to send me a democode,
> which he has tested on SunOS running 3.00/6 (see code below).
> Probably, this code works fine on Intel architecture, too?
> However, it does not work on my Mac running LinuxPPC.
> 
> Sorrowly, I had some problems in creating the makefile for my
> system, then I had to reformat my harddisk, which took some time,
> so I am only now able to report my results.
> 
> First, I did a new clean install of my system:
> PowerBook G3 with LinuxPPC 2000 Q4 using root 3.01/06.
> 
> Then I compiled the democode:
> [christian@pbook eddy]$ gmake -f Makefile4doit
> g++ -O -Wall -fsigned-char -I/usr/X11/include
> -I/home/christian/rt/root/include -c main.cxx
> main.cxx: In function `void CreateOutput(TString &)':
> main.cxx:43: warning: unused variable `class TBranch * br'
> g++ -O -Wall -fsigned-char -I/usr/X11/include
> -I/home/christian/rt/root/include -c MyClass.cxx
> g++ -O -Wall -fsigned-char -I/usr/X11/include
> -I/home/christian/rt/root/include -c MyClassDict.cxx
> g++ -shared  -fPIC -O -o libMyClass.so MyClass.o MyClassDict.o
> libMyClass.so done
> g++ -O -o doit main.o -L. -lMyClass -L/home/christian/rt/root/lib -lCore
> -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix
> -lPhysics -lm -ldl -rdynamic
> doit done
> 
> However, the output of the democode is as follows:
> [christian@pbook eddy]$ ./doit
> Filling tree
> ******************************************************************************
> 
> *Tree    :stuff     : MyClass entries
> *
> *Entries :        0 : Total =               0 bytes  File  Size =          0
> *
> *        :          : Tree compression factor =   1.00
> *
> ******************************************************************************
> 
> *Branch  :MyClass
> *
> *Entries :        0 : BranchElement (see below)
> *
> *............................................................................*
> 
> *Br    0 :TObject   :
> *
> *Entries :        0 : Total  Size=          0 bytes  File Size  =          0
> *
> *Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
> *
> *............................................................................*
> 
> *Br    1 :fA        :
> *
> *Entries :        0 : Total  Size=          0 bytes  File Size  =          0
> *
> *Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
> *
> *............................................................................*
> 
> *Br    2 :fS        :
> *
> *Entries :        0 : Total  Size=          0 bytes  File Size  =          0
> *
> *Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
> *
> *............................................................................*
> 
> Reading tree
> 0: size = 0
> 1: size = 0
> 2: size = 0
> 3: size = 0
> 4: size = 0
> 5: size = 0
> 6: size = 0
> 7: size = 0
> 8: size = 0
> 9: size = 0
> 10: size = 0
> 11: size = 0
> 12: size = 0
> 13: size = 0
> 14: size = 0
> 15: size = 0
> 16: size = 0
> 17: size = 0
> 18: size = 0
> 19: size = 0
> 20: size = 0
> 21: size = 0
> 22: size = 0
> 
> IMPORTANT: This means that I can recreate my problem with the new
> branch style with the demo example, since when I add the following
> line in function CreateOutput(...) just before setting the branch:
>     tree->SetBranchStyle(0);  // <== new line added to use BranchOld()
>     TBranch *br  = tree->Branch("MyClass","MyClass",&c,bsize,split);
> then everything works as expected:
> [christian@pbook eddy]$ ./doit
> Filling tree
> ******************************************************************************
> 
> *Tree    :stuff     : MyClass entries
> *
> *Entries :       10 : Total =               0 bytes  File  Size =          0
> *
> *        :          : Tree compression factor =   1.00
> *
> ******************************************************************************
> 
> *Branch  :MyClass   : MyClass
> *
> *Entries :       10 : BranchObject (see below)
> *
> *............................................................................*
> 
> *Br    0 :fA.fArray : fA.fArray[fA.fN]/D
> *
> *Entries :       10 : Total  Size=          0 bytes  File Size  =          0
> *
> *Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
> *
> *............................................................................*
> 
> *Br    1 :fA.fN     :
> *
> *Entries :       10 : Total  Size=          0 bytes  File Size  =          0
> *
> *Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
> *
> *............................................................................*
> 
> *Br    2 :fS.fData  : fData/C
> *
> *Entries :       10 : Total  Size=          0 bytes  File Size  =          0
> *
> *Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
> *
> *............................................................................*
> 
> *Br    3 :fUniqueID :
> *
> *Entries :       10 : Total  Size=          0 bytes  File Size  =          0
> *
> *Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
> *
> *............................................................................*
> 
> *Br    4 :fBits     :
> *
> *Entries :       10 : Total  Size=          0 bytes  File Size  =          0
> *
> *Baskets :        0 : Basket Size=      64000 bytes  Compression=   1.00
> *
> *............................................................................*
> 
> Reading tree
> 0: size = 1 aap
> 1: size = 2 aap
> 2: size = 3 aap
> 3: size = 4 aap
> 4: size = 5 aap
> 5: size = 6 aap
> 6: size = 7 aap
> 7: size = 8 aap
> 8: size = 9 aap
> 9: size = 10 aap
> 
> Now I have the following questions:
> What could be the reason that on my machine the new branch()
> function does not work?
> I suppose, the code works fine on Linux for Intelx86?
> Could this be a processor-specific problem?
> Since the Mac uses a PowerPC processor, do you know if the
> code runs fine on an IBM RS6000?
> 
> Thank you very much in advance.
> 
> Best regards
> Christian
> -------------------------------------
> C.h.r.i.s.t.i.a.n  S.t.r.a.t.o.w.a
> V.i.e.n.n.a,  A.u.s.t.r.i.a
> 
> 
> //-----main.cxx----------------------------------------
>  #include <TROOT.h>
> #include <TFile.h>
> #include <TTree.h>
> #include <TSystem.h>
> #include <Rtypes.h>
> #include <TArrayD.h>
> #include <TError.h>
> 
> #include <iostream.h>
> 
> #include "MyClass.h"
> 
> void CreateOutput(TString &file);
> void LoadOutput(TString &file);
> 
> int main(Int_t argc, Char_t **argv)
> {
>   TROOT showit("showit","showit");
> 
>   TString file = "sample.txt";
>   CreateOutput(file);
>   LoadOutput(file);
> 
>   return 0;
> }
> 
> //________________________
> void CreateOutput(TString  &file)
> {
>   TFile *tfile = new TFile(file.Data(),"RECREATE","file filed with MyClass",1);
>   TTree *tree  = new TTree("stuff","MyClass entries");
> 
>   Int_t split = 1;
>   Int_t bsize = 64000;
>   MyClass *c = new MyClass();
> //  tree->SetBranchStyle(0);  //use BranchOld()
>   TBranch *br  = tree->Branch("MyClass","MyClass",&c,bsize,split);
> 
>   printf("Filling tree\n");
>   for (Int_t i = 0; i < 10; i++)
>   {
>     (c->fA).Set(i+1); // Set array length to i+1
>     (c->fA).Reset(i); // Set all values to i
>     c->fS = "aap";
>     tree->Fill();
>   }
>   tree->Print();
> 
>   tfile->Write();
>   tfile->Close();
> }
> 
> //______________________
> void LoadOutput(TString &file)
> {
>   TFile tfile(file.Data());
>   TTree *tr = (TTree*)gDirectory->Get("stuff");
> 
>   MyClass* c = new MyClass();
>   tr->SetBranchAddress("MyClass",&c);
> 
>   printf("Reading tree\n");
>   Int_t nrBytes = 0;
>   for (Int_t j = 0; j < tr->GetEntries(); j++)
>   {
>     nrBytes += tr->GetEvent(j);
>     printf("%d: size = %d %s\n",j,(c->fA).GetSize(),(c->fS).Data());
>   }
> 
>   delete tr;
> }
> 
> 
> //-----MyClass.h---------------------------------------
>  #ifndef MYCLASS
> #define MYCLASS
> 
> #include <TObject.h>
> #include <Rtypes.h>
> #include <TString.h>
> #include <TTree.h>
> #include <TError.h>
> 
> class MyClass : public TObject
> {
> public:
>   TArrayD fA;
>   TString fS;
> 
> public:
>   MyClass();
>   virtual ~MyClass();
>   ClassDef(MyClass,1)  //MyClass
> };
> 
> #endif
> 
> //-----MyClass.cxx-------------------------------------
>  #include "MyClass.h"
> 
> ClassImp(MyClass);
> 
> MyClass::MyClass()
> {
> }
> 
> MyClass::~MyClass()
> {
> }
> 
> //-----MyClass_LinkDef.h-------------------------------
>  #ifdef __CINT__
> 
> #pragma link off all globals;
> #pragma link off all classes;
> #pragma link off all functions;
> 
> #pragma link C++ class MyClass+;
> 
> #endif
> 
> //-----Makefile4doit-----------------------------------
> # Makefile for doit.
> # modified from root example Event
> # shell: gmake -f Makefile4doit
> 
> ARCH          = linuxppcegcs
> 
> CXX           =
> ObjSuf        = o
> SrcSuf        = cxx
> ExeSuf        =
> DllSuf        = so
> OutPutOpt     = -o
> 
> LPATH         = .
> MYCLASSLIB    = -L$(LPATH) -lMyClass
> 
> ROOTCFLAGS   := $(shell root-config --cflags)
> ROOTLIBS     := $(shell root-config --libs)
> ROOTGLIBS    := $(shell root-config --glibs)
> 
> 
> ifeq ($(ARCH),linuxegcs)
> # Linux with egcs (>= RedHat 5.2)
> CXX           = g++
> CXXFLAGS      = -I ./ -O -Wall -fPIC
> LD            = g++
> LDFLAGS       = -O
> SOFLAGS       = -shared
> endif
> 
> ifeq ($(ARCH),linuxppcegcs)
> # MkLinux with egcs/glibc
> CXX           = g++
> CXXFLAGS      = -O -Wall
> LD            = g++
> LDFLAGS       = -O
> SOFLAGS       = -shared  -fPIC
> endif
> 
> CXXFLAGS     += $(ROOTCFLAGS)
> LIBS          = $(ROOTLIBS) $(SYSLIBS)
> GLIBS         = $(ROOTGLIBS) $(SYSLIBS)
> 
> #--------
> 
> MYCLASSO        = MyClass.$(ObjSuf) \
>                 MyClassDict.$(ObjSuf)
> 
> MYCLASSS        = MyClass.$(SrcSuf) \
>                 MyClassDict.$(SrcSuf)
> 
> MAINO           = main.$(ObjSuf)
> MAINS           = main.$(SrcSuf)
> 
> MAIN            = doit$(ExeSuf)
> MYCLASSSO       = libMyClass.$(DllSuf)
> 
> OBJS          = $(MYCLASSO) $(MAINO)
> 
> PROGRAMS      = $(MAIN)
> 
> #--------
> 
> .SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf)
> 
> all:            $(PROGRAMS)
> 
> $(MYCLASSSO):     $(MYCLASSO)
>  $(LD) $(SOFLAGS) $(LDFLAGS) $(OutPutOpt) $(MYCLASSSO) $(MYCLASSO)
>  @echo "$@ done"
> 
> $(MAIN):       $(MAINO) $(MYCLASSSO)
>  $(LD) $(LDFLAGS) $(OutPutOpt) $(MAIN) $(MAINO) $(MYCLASSLIB) $(LIBS)
>  @echo "$@ done"
> 
> clean:
>  @rm -f $(OBJS) core
> 
> distclean:      clean
>  @rm -f $(PROGRAMS) $(MYCLASSSO) $(MYCLASSLIB) *Dict.* *.def *.exp \
>   *.root *.ps *.so .def so_locations
> #  @rm -rf cxx_repository
> 
> .SUFFIXES: .$(SrcSuf)
> 
> ###
> 
> MyClass.$(ObjSuf): MyClass.h
> doit.$(ObjSuf): MyClass.h
> 
> MyClassDict.$(SrcSuf): MyClass.h MyClass_LinkDef.h
>  @echo "Generating dictionary MyClassDict..."
>  @rootcint -f MyClassDict.$(SrcSuf) -c MyClass.h MyClass_LinkDef.h
> 
> .$(SrcSuf).$(ObjSuf):
>  $(CXX) $(CXXFLAGS) -c $<
> 
> #---------------------------------------------
> 
> Rene Brun wrote:
> 
> > Hi Christian,
> >
> > You can have your libraries where you want. They don't need to be
> > in $ROOTSYS/lib !
> > Concerning your problem, you do not provide enough information.
> > Did you set the branch address ?
> > You can get an idea of what happens (with version 3.01/05) by activating
> > the debug flag. Just before the loop on entries, add the statement
> >   gDebug = 2;  (in TSystem.h)
> >
> > Rene Brun
> >
> > On Sat, 16 Jun 2001 cstrato@EUnet.at wrote:
> >
> > > Dear Rene
> > >
> > > Thank you for your suggestion. Sorrowly, the problem persists
> > > with version 3.01/05.
> > >
> > > Regarding your second suggestion, until now I have not been
> > > able to extract a subset where the problem can be reproduced.
> > > I have tried to create test classes, but the problem never
> > > appeared.
> > >
> > > However, I know exactly where the program crashes:
> > > // The following command is still ok:
> > >    Int_t  vNEntries = (Int_t)(vTree->GetEntries());
> > > cout << "vNEntries <" << vNEntries << ">" << endl;
> > >    for (Int_t i=0;i<vNEntries;i++) {
> > > // The following line crashes!!
> > >       vTree->GetEntry(i);
> > >       some code;
> > >    }//for_i
> > >
> > > Although there are entries in the tree, it cannot get the
> > > entries.
> > > Maybe, you can give me some hints where to look further?
> > >
> > > I have seen that the option Bronch() requires access to the
> > > library where the corresponding class is defined.
> > > Since my libs are stored in /opt/rootcode maybe Bronch()
> > > cannot access the corresponding library, although it is
> > > loaded first with gSystem->Load(lib).
> > > Could it be that I need to store my own libraries also
> > > in /opt/root/lib in order for Bronch() to find the
> > > corresponding class?
> > >
> > > Thank you for your help.
> > > Best regards
> > > Christian
> > >
> > > Rene Brun wrote:
> > >
> > > > Hi Christian,
> > > >
> > > > Let me suggest two things:
> > > >  1- could you try with the version 3.01/5 now released including the
> > > >    version for PPPLinux, thanks to Damir).
> > > >  2- if the problem persists, prepare a tar file with a very small subset
> > > >   of your classes such that I can reproduce the problem.
> > > >
> > > > Note that, as I explained in a previous mail, we will not have frequent
> > > > access to the Internet in the coming 10 days.
> > > >
> > > > Rene Brun
> > > >
> > > > On Fri, 8 Jun 2001 cstrato@EUnet.at wrote:
> > > >
> > > > >
> > > > > Dear Rene, dear Rooters
> > > > >
> > > > > In my first root file I store a tree with one branch that addresses a
> > > > > class,
> > > > > which is derived from TNamed, but contains as member variables two
> > > > > TStrings
> > > > > and a couple of integer variables. Thus I had to set the splitlevel to
> > > > > zero
> > > > > in my first library in earlier versions of root.
> > > > >
> > > > > My second library creates a new root file and stores a couple of trees
> > > > > with
> > > > > branches containing only integers and doubles. However, it accesses the
> > > > > tree
> > > > > from the first root file to get some data.
> > > > >
> > > > > This second library works fine as long as it accessed the first root
> > > > > file
> > > > > created with the old Tree::Branch() function. However, now I have
> > > > > recreated
> > > > > the first root file, which uses now the new Tree::Branch function (since
> > > > >
> > > > > I am using now 3.01/02). Now the second library crashes with a
> > > > > "segmentation
> > > > > violation".
> > > > >
> > > > > After setting "Tree->SetBranchStyle(0)" in my first library for the
> > > > > branch
> > > > > containing TStrings and integers, everything works fine again. It seems
> > > > > that
> > > > > simply setting split=0 in the new Branch() is not enough.
> > > > >
> > > > > My question now is:
> > > > > Why do I have to use BranchOld() when my class contains TStrings?
> > > > >
> > > > > My system: PowerBook running LinuxPPC 2000, root 3.01/02.
> > > > >
> > > > > Thank you in advance for your help.
> > > > >
> > > > > Best regards
> > > > > Christian
> > > > > ----------------------------------
> > > > > C.h.r.i.s.t.i.a.n  S.t.r.a.t.o.w.a
> > > > > V.i.e.n.n.a,  A.u.s.t.r.i.a
> > > > >
> > > > >
> > >
> 



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:57 MET