Several tree /split=1 problems

Eddy Offermann (eddy@puma.rentec.com)
Wed, 17 Mar 99 22:01:16 EST


Dear ROOT-ers

I have several problems when creating a tree in a ROOT file . I have tried to
summarize it in a small example (showit) for which the files are listed below.

Problems:
1) using TArrayI ... in my class with split = 1

When running my example with split = 0, I get the following output:
Creating a tree: ./showit

******************************************************************************
*Tree :T : tree *
*Entries : 1000 : Total Size = 46888 bytes File Size = 23488 *
* : : Tree compression factor = 2.04 *
******************************************************************************
*Branch :Super : Super *
*Entries : 1000 : Total Size = 45800 bytes File Size = 22400 *
*Baskets : 200 : Basket Size = 256 bytes Compression= 2.04 *
*............................................................................*

Reading the tree: ./showit -r

nrEntries: 1000
fVar1 5 var1
fVar2.*fArray 1 Array of fN 32 bit integers
fVar2.fN 2 Number of array elements
fUniqueID 0 object unique identifier
fBits 50331648 bit field status word
var2[0] = 1 var2[1] = 2
fVar1 5 var1
fVar2.*fArray 1 Array of fN 32 bit integers
fVar2.fN 2 Number of array elements
fUniqueID 0 object unique identifier
fBits 50331648 bit field status word
var2[0] = 1 var2[1] = 2

Conclusion: This looks fine !!
----------

Changing it to split = 1 gives for both cases the following:

Creating a tree: ./showit
******************************************************************************
*Tree :T : tree *
*Entries : 1000 : Total Size = 21800 bytes File Size = 7637 *
* : : Tree compression factor = 3.16 *
******************************************************************************
*Branch :Super : Super *
*Entries : 1000 : BranchObject (see below) *
*............................................................................*
*Branch :fVar1 : fVar1 *
*Entries : 1000 : Total Size = 5060 bytes File Size = 1580 *
*Baskets : 20 : Basket Size = 256 bytes Compression= 3.20 *
*............................................................................*
*Branch :fVar2.fN : fVar2.fN *
*Entries : 1000 : Total Size = 5292 bytes File Size = 1722 *
*Baskets : 21 : Basket Size = 256 bytes Compression= 3.07 *
*............................................................................*
*Branch :fUniqueID : fUniqueID *
*Entries : 1000 : Total Size = 5313 bytes File Size = 1680 *
*Baskets : 21 : Basket Size = 256 bytes Compression= 3.16 *
*............................................................................*
*Branch :fBits : fBits *
*Entries : 1000 : Total Size = 5060 bytes File Size = 1580 *
*Baskets : 20 : Basket Size = 256 bytes Compression= 3.20 *
*............................................................................*

Reading the tree: ./showit -r
nrEntries: 1000
fVar1 5 var1
fVar2.*fArray ->0 Array of fN 32 bit integers
fVar2.fN 2 Number of array elements
fUniqueID 0 object unique identifier
fBits 50331648 bit field status word

*** Break *** segmentation violation
Abort (core dumped)

Conclusion: fVar2.fArray was not stored ???? Why not ?
----------

2) Large baskets in split = 0 and 1

I increase the buffer size to 64000 ad get in split=0 the following:
******************************************************************************
*Tree :T : tree *
*Entries : 1000 : Total Size = 2155 bytes File Size = 2155 *
* : : Tree compression factor = 1.00 *
******************************************************************************
*Branch :Super : Super *
*Entries : 1000 : Total Size = 0 bytes File Size = 0 *
*Baskets : 0 : Basket Size = 64000 bytes Compression= 1.00 *
*............................................................................*

When reading back, the file seems to contain all the data, so just
the tree->Print() gives the wrong info ??

3) enum in split = 1
I changed the members of MyClass to:
Int_t fVar1; //var1
TArrayI fVar2; //var2
ENumbers fVar3; //var3

with
typedef enum { kZero, kOne } ENumbers;

reading and writing in split = 0 works fine but in split =1 fVar3 is
completely ignored just like fVar2.fArray

Best Regards,
Eddy Offermann

*************************************************************************
Below are my Makefile, MyClass_LinkDef.h, main.C, MyClass.C and MyClass.h

------------------- Makefile ----------
ObjSuf = o
SrcSuf = C
DllSuf = so

ROOTLIBS = -L$(ROOTSYS)/lib -lRint -lNew -lBase -lCint -lClib -lCont -lFunc \
-lGraf -lGraf3d -lHist -lHtml -lMatrix -lMeta -lMinuit -lNet \
-lPostscript -lProof -lTree -lUnix -lZip
ROOTGLIBS = -lGpad -lGui -lGX11 -lX3d

# Solaris
CC = CC
CCFLAGS = -O -KPIC -I./ -I$(ROOTSYS)/include
LD = CC
LDFLAGS = -g
SOFLAGS = -G

LIBS = $(ROOTLIBS) $(ROOTGLIBS) -L/usr/openwin/lib \
-L/usr/ccs/lib -lXpm -lX11 -lm -lgen -ldl -lsocket -lsunmath

OBJS = main.$(ObjSuf) MyClass.$(ObjSuf) MyClassDict.$(ObjSuf)

PROGRAMS = showit

all: $(PROGRAMS)

$(PROGRAMS): $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAMS)
@echo "$(RENROOT) done"

clean:
@rm -f $(OBJS) core \
MyClassDict.$(SrcSuf) MyClassDict.h

.SUFFIXES: .$(SrcSuf)

###

main.o: MyClass.h
MyClassDict.$(SrcSuf): MyClass.h
@echo "Generating MyClass dictionary"
@rootcint -f MyClassDict.$(SrcSuf) -c MyClass.h MyClass_LinkDef.h

.$(SrcSuf).$(ObjSuf):
$(CC) $(CCFLAGS) -c $<

------------------- 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

------------------- main.C ----------

#include "TROOT.h"
#include "TFile.h"
#include "TTree.h"
#include "TBranch.h"

#include "MyClass.h"

int main(int argc, char **argv)
{
TROOT simple("simple","Example of creation of a tree");

// Just give any kind of argument and the file is read
// otherwise written.

Int_t read = 0;
Int_t write = 0;
if (argc > 1) read = 1;
else write = 1;

TFile *hfile;
if (write) hfile = new TFile("example","RECREATE","Demo ROOT file");
else hfile = new TFile("example");

MyClass *c = new MyClass();
Int_t nrEntries = 0;
Int_t nrBytes = 0;

if (write)
{
Int_t array[2];
array[0] = 1;
array[1] = 2;
c->SetVar1(5);
c->SetVar2(2,array);

Int_t split = 0;
Int_t bsize = 256;
TTree *tree = new TTree("T","tree");
TBranch *br = tree->Branch("Super","MyClass",&c,bsize,split);

for (Int_t i = 0; i < 1000; i++)
{
nrBytes += tree->Fill();
nrEntries++;
}
hfile->Write();
tree->Print();
}
else
{
TTree *tree = (TTree*) hfile->Get("T");
TBranch *br = tree->GetBranch("Super");
br->SetAddress(&c);
Int_t nrEntries = (Int_t) tree->GetEntries();
printf("nrEntries: %d\n",nrEntries);
for (Int_t i = 0; i < 1000; i++)
{
nrBytes += tree->GetEvent(i);
if (i ==0 || i==999)
{
c->Dump();
TArrayI var2 = c->GetVar2();
printf("var2[0] = %d var2[1] = %d\n",var2[0],var2[1]);

}
}
}

hfile->Close();

return 0;
}

------------------- MyClass.C ----------

#include <MyClass.h>

ClassImp(MyClass)

//______________________________________________________________________________
MyClass::MyClass()
{
fVar1 = 0;
fVar2.Set(0);
}

//______________________________________________________________________________
MyClass::~MyClass()
{
}

------------------- MyClass.h ----------

#ifndef ROOT_MyClass
#define ROOT_MyClass

#include <TObject.h>
#include <TArrayI.h>

class MyClass : public TObject {
public:

Int_t fVar1; //var1
TArrayI fVar2; //var2

MyClass();
virtual ~MyClass();

Int_t GetVar1() { return fVar1;}
TArrayI& GetVar2() { return fVar2;}
void SetVar1(Int_t val) { fVar1 = val;}
void SetVar2(Int_t nr, Int_t *val) { fVar2.Set(nr,val);}

ClassDef(MyClass,1) //MyClass structure
};

#endif