Problem making a TTree out of a class

Hi forum,

a newbie question I havent been able to solve myself studying the guidebook: I want to make a TTree out of a class. This is illustrated below in a simple example. This fails with the error
"Error in TTree:Bronch:Cannot find class:numbers"
What should I do to make it work?

#include <stdio.h>
#include <stdlib.h>
#include <TTree.h>
#include <TFile.h>

class numbers
{
public:
int one;
int two;
int three;

};

int main()
{
numbers g;

TFile *f = new TFile(“mytree.root”,“recreate”);
TTree *t = new TTree(“t”,“my test tree”);
t->Branch(“my branch”,“numbers”,&g,10000,0);

g.one = 1;
g.two = 2;
g.three = 3;

t->Fill();

t->Write();
f->Close();

delete f;
delete t;

return 1;

}

thanks
mett

Hi,

You need to generate the dictionary for the class ‘numbers’. See the User’s guide for details (i.e. you will need to use rootcint -f mydict.cxx -c myheader.h mylinkdef.h and compile and link the result) or simply load your whole file using ACLiC into root (i.e. rather than calling the compiler yourself simply doroot [] .L myscript.C+ACLiC will take care of running rootcint, the compiler and the linker for you.

Cheers,
Philippe.

I still dont manage to do this… I can make the dictionary, link it and compile it, but it crashed when trying to create a TBranch using the class “numbers”. I would be very grateful if someone could give me a hint what to do

I have a class header and source file (number.hpp/cpp) and a main file test.cpp where the class is used (see below). I create the dictionary using
rootcint -f mydict.cpp numbers.hpp LinkDef.h
then compile and and link the result with the main file (I include the mydict.hpp in the main file, correct?). I have included the Makefile below. This works without errors, but when I execute the executable I get a segmentation violation at the point in the code when the Branch is created (which uses the class “numbers”). This is where Im stuck. If anybody have a clue, please tell me.

cheers
/Mett

//header file
#include <TObject.h>

#ifndef NUMBERS_H
#define NUMBERS_H

class numbers
{
public:
numbers();
~numbers();
int one;
int two;
int three;
ClassDef(numbers,1);
};

#endif

// main file
#include <stdio.h>
#include <stdlib.h>
#include <TTree.h>
#include <TFile.h>
#include “mydict.h”
#include “numbers.hpp”

int main()
{
numbers g;

TFile *f = new TFile(“mytree.root”,“recreate”);
TTree *t = new TTree(“t”,“my test tree”);

t->Branch(“my branch”,“numbers”,&g,10000,0);

g.one = 1;
g.two = 2;
g.three = 3;

t->Fill();

t->Write();
f->Close();

delete f;
delete t;

return 1;

}

CC = g++

CFLAGS = -fPIC
ALL_CFLAGS = -Wall -O6 $(CFLAGS)

LIBS = -L/nfs/d22/hfm/hess/Base_Software_Linux64_gcc4.1c/usr/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -pthread -lm -ldl -rdynamic
INCS = -I/nfs/d22/hfm/hess/Base_Software_Linux64_gcc4.1c/usr/include/root/

EXE = test.exe

%.o : %.cpp Makefile
$(CC) $(ALL_CFLAGS) $(INCS) -c $< -o $@

all: $(EXE)

OBJS = mydict.o numbers.o test.o

$(EXE): $(OBJS) Makefile
$(CC) $(ALL_CFLAGS) $(INCS) $(OBJS) $(LIBS) -o $(EXE)

.PHONY : clean
clean:
rm -f *.o *.exe

[quote=“pcanal”]Hi,

You need to generate the dictionary for the class ‘numbers’. See the User’s guide for details (i.e. you will need to use rootcint -f mydict.cxx -c myheader.h mylinkdef.h and compile and link the result) or simply load your whole file using ACLiC into root (i.e. rather than calling the compiler yourself simply doroot [] .L myscript.C+ACLiC will take care of running rootcint, the compiler and the linker for you.

Cheers,
Philippe.[/quote]

If this:[quote]rootcint -f mydict.cpp numbers.hpp LinkDef.h [/quote]is literal then you are missing a -c as the 3rd argument:rootcint -f mydict.cpp -c numbers.hpp LinkDef.h
Cheers,
Philippe.

numbers g; .... t->Branch("my branch","numbers",&g,10000,0); The support for this syntax is relatively recent (v5.20 and up). With older version of ROOT, you need to use numbers * g = new numbers; ... t->Branch("my branch","numbers",&g,10000,0);

Cheers,
Philippe.

Hi again,

still some problems. As before, I can generate the dictionary and a shared library from my class (“numbers”, below) using the Makefile included below. Also, I can load this library and use my class to define a tree WHEN using root interactively. However, when I try to use the class in a similar fashion in a compiled script, it crashes with

*** Break *** segmentation violation
e[?1034hUsing host libthread_db library “/lib64/libthread_db.so.1”.
Attaching to program: /proc/21976/exe, process 21976
[Thread debugging using libthread_db enabled]
[New Thread 0x2b5eecb9c330 (LWP 21976)]
0x00002b5eec6b1fa5 in waitpid () from /lib64/libc.so.6
#1 0x00002b5eec658131 in ?? () from /lib64/libc.so.6
#2 0x00002b5ee8608a09 in TUnixSystem::StackTrace ()
from /nfs/d22/hfm/hess/Base_Software_Linux64_gcc4.1c/usr/lib/root/libCore.so.5.16
#3 0x00002b5ee8607aec in TUnixSystem::DispatchSignals ()
from /nfs/d22/hfm/hess/Base_Software_Linux64_gcc4.1c/usr/lib/root/libCore.so.5.16
#4
#5 0x0000000000844f40 in ?? ()
#6 0x0000000000400d8d in main ()
The program is running. Quit anyway (and detach it)? (y or n) [answered Y; input not from terminal]
Detaching from program: /proc/21976/exe, process 21976

Any hints, suggestions, what I can do to fix this are appreciated. Im using root version 5.16

/Mett

main file

#include <stdio.h>
#include <stdlib.h>
#include <TTree.h>
#include <TFile.h>
#include "numbers.hpp"

int main()
{

  Int_t j;

  numbers *g = new numbers;
  
  TFile *f = new TFile("mytree.root","recreate");
  TTree *t = new TTree("t","my test tree");

  t->Branch("mybranch","numbers",&g,10000,0);

  g->one = 1;
  g->two = 2;
  g->three = 3;

  t->Fill();

  t->Write();
  f->Close();

  delete f;
  delete t;
  
  return 1;

}

class header file (i have excluded the src file)

#include <TObject.h>

#ifndef NUMBERS_H
#define NUMBERS_H

class numbers : public TObject
{
public:
  numbers();
  ~numbers();

  //void Streamer(TBuffer &R__b);

  int one;
  int two;
  int three;

  ClassDef(numbers,1);

};

#endif

makefile for generating the dictionary and library

CC = g++

CFLAGS = -fPIC
ALL_CFLAGS = -Wall -O6 $(CFLAGS)

ROOTLIBS = `root-config --cflags`
ROOTLDFLAGS = `root-config --ldflags`
#ROOTINCS = `root-config --`

LIBS = -L/nfs/d22/hfm/hess/Base_Software_Linux64_gcc4.1c/usr/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -pthread -lm -ldl -rdynamic 
INCS = -I/nfs/d22/hfm/hess/Base_Software_Linux64_gcc4.1c/usr/include/root/

LIBS = numbers.so

numbers.o : numbers.cpp Makefile
	$(CC) $(ALL_CFLAGS) $(INCS) -c $< -o $@

numbers.so : numbers.o Dictionary.o
	$(CC) -shared -O $(ROOTLDFLAGS) $^ -o $@

Dictionary.o : Dictionary.cpp
	$(CC) -O -Wall -fPIC $(ROOTLIBS) -c $^

Dictionary.cpp : numbers.hpp LinkDef.h
	rootcint -f $@ -c $^

libs: $(LIBS)

.PHONY : clean
clean:
	rm -f *.o *.exe

[code] t->Write();
f->Close();

delete f;
delete t; [/code]The TTree object is owned by the TFile and is deleted when the file is ‘Closed’. Hence ‘delete t’ resulst in a double delete. Use just [code] t->Write();
f->Close();

delete f; [/code]

Cheers,
Philippe.