Hi,
Please find attached a slightly modified "set" :
- MakeClass.cxx - the modified MakeClass macro
- ntuple.hxx, ntuple.cxx - example files generated for the
$ROOTSYS/tutorials/hsimple.root file
- Makefile - Linux EGCS Makefile which creates the ntuple.so
( The main change in the MakeClass.cxx is related to the C++ include file
extension convention - I used .hpp, but I think I should use .hxx, as it
is in perfect agreement with .cxx C++ source code file extension. )
Have fun,
Jacek.
//_____________________________________________________________________________
Int_t MakeClass(TTree *t, const char *classname = 0)
{
//====>
//*-*-*-*-*-*-*Generate skeleton analysis class for this Tree*-*-*-*-*-*-*
//*-* ==============================================
//
// The following files are produced: classname.hxx and classname.cxx
// if classname is NULL, classname will be nameoftree.
//
// The generated code in classname.hxx includes the following:
// - Identification of the original Tree and Input file name
// - Definition of analysis class (data and functions)
// - the following class functions:
// -constructor (connecting by default the Tree file)
// -GetEvent(Int_t event)
// -Init(TTree *tree) to initialize a new TTree
// -Show(Int_t event) to read and Dump event
//
// The generated code in classname.cxx includes only the main
// analysis function Loop.
//
// To use this function:
// - connect your Tree file (eg: TFile f("myfile.root");)
// - T->MakeClass("MyClass");
// where T is the name of the Tree in the myfile.root file,
// and MyClass.hxx, MyClass.cxx are names of files created by this function.
// In a Root session, you can do:
// Root > .L MyClass.cxx
// Root > MyClass t
// Root > t.GetEvent(12); // Fill t data members with event number 12
// Root > t.Show(); // Show values of event 12
// Root > t.Show(16); // Read and show values of event 16
// Root > t.Loop(); // Loop on all events
//
//====>
// Check against an invalid Tree pointer
if (!t) return 1;
if (!t->IsA()->InheritsFrom("TTree")) {
printf("Attempt to MakeClass for a non-TTree object\n");
return 2;
}
// Connect output files
char *thead = new char[256];
if (!classname) classname = t->GetName();
sprintf(thead,"%s.hxx",classname);
FILE *fp = fopen(thead,"w");
if (!fp) {
printf("Cannot open output file:%s\n",thead);
delete [] thead;
return 3;
}
char *tcimp = new char[256];
sprintf(tcimp,"%s.cxx",classname);
FILE *fpc = fopen(tcimp,"w");
if (!fpc) {
printf("Cannot open output file:%s\n",tcimp);
delete [] thead;
delete [] tcimp;
return 3;
}
char *treefile = new char[1000];
if (t->GetDirectory() && t->GetDirectory()->GetFile())
strcpy(treefile,t->GetDirectory()->GetFile()->GetName());
else strcpy(treefile,"Memory Directory");
//======================Generate classname.hxx=====================
// Print header
TObjArray *leaves = t->GetListOfLeaves();
Int_t nleaves = leaves->GetEntriesFast();
TDatime td;
fprintf(fp,"//////////////////////////////////////////////////////////\n");
fprintf(fp,"// This class has been automatically generated \n");
fprintf(fp,"// (%s by ROOT version%s)\n",td.AsString(),gROOT->GetVersion());
fprintf(fp,"// from TTree %s/%s\n",t->GetName(),t->GetTitle());
fprintf(fp,"// found on file: %s\n",treefile);
fprintf(fp,"//////////////////////////////////////////////////////////\n");
fprintf(fp,"\n");
fprintf(fp,"\n");
fprintf(fp,"#ifndef %s_hxx\n",classname);
fprintf(fp,"#define %s_hxx\n",classname);
fprintf(fp,"\n");
fprintf(fp,"#ifndef __CINT__\n");
fprintf(fp,"#include \"TROOT.h\"\n");
fprintf(fp,"#include \"TBranch.h\"\n");
fprintf(fp,"#include \"TTree.h\"\n");
fprintf(fp,"#include \"TFile.h\"\n");
fprintf(fp,"#else\n");
fprintf(fp,"class TBranch;\n");
fprintf(fp,"class TTree;\n");
fprintf(fp,"class TFile;\n");
fprintf(fp,"#endif\n");
fprintf(fp,"\n");
fprintf(fp,"class %s {\n",classname);
fprintf(fp," public :\n");
fprintf(fp," TTree *fTree; //pointer to the analyzed TTree\n");
fprintf(fp," Int_t fEvent; //current Event number\n");
// First loop on all branches to generate branch declarations
fprintf(fp,"//Declaration of branches\n");
Int_t nb, i;
nb = t->GetListOfBranches().GetEntriesFast();
for (i=0;i<nb;i++) {
branch = (TBranch*)t->GetListOfBranches().UncheckedAt(i);
fprintf(fp,"%s%-15s branch_%s;\n"," ","Int_t", branch->GetName());
fprintf(fp,"%s%-15s *branch_pointer_%s;\n"," ","TBranch", branch->GetName());
}
// First loop on all leaves to generate leaf declarations
fprintf(fp,"//Declaration of leaves\n");
Int_t len, l;
TLeaf *leafcount;
TLeafObject *leafobj;
char *bname;
const char *headOK = " ";
const char *headcom = " //";
const char *head;
char branchname[64];
for (l=0;l<nleaves;l++) {
TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
len = leaf->GetLen();
leafcount =leaf->GetLeafCount();
TBranch *branch = leaf->GetBranch();
if (leafcount) strcpy(branchname,branch->GetName());
else strcpy(branchname,leaf->GetTitle());
char *twodim = (char*)strstr(leaf->GetTitle(),"][");
bname = branchname;
while (*bname) {if (*bname == '.') *bname='_'; bname++;}
if (branch->IsA() == TBranchObject::Class()) {
if (branch->GetListOfBranches()->GetEntriesFast()) continue;
leafobj = (TLeafObject*)leaf;
if (leafobj->GetClass()) head = headOK;
else head = headcom;
fprintf(fp,"%s%-15s *%s;\n",head,leafobj->GetTypeName(), leafobj->GetName());
continue;
}
if (leafcount) {
len = leafcount->GetMaximum();
if (twodim) {
fprintf(fp," %-15s %s[%d]%s;\n",leaf->GetTypeName(), branchname,len,(char*)(twodim+1));
} else {
fprintf(fp," %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
}
} else {
fprintf(fp," %-15s leaf_%s;\n",leaf->GetTypeName(), branchname);
fprintf(fp," %-15s &%s() {",leaf->GetTypeName(), branchname);
fprintf(fp,"if (branch_%s) return leaf_%s;",branch->GetName(), branchname);
fprintf(fp,"branch_pointer_%s->GetEvent(fEvent);",branch->GetName());
fprintf(fp,"branch_%s = 1; return leaf_%s;}\n",branch->GetName(), branchname);
// fprintf(fp," %-15s %s(%s value) {return leaf_%s = value;}\n",leaf->GetTypeName(), branchname, leaf->GetTypeName(), branchname);
}
}
// generate class member functions prototypes
fprintf(fp,"\n");
fprintf(fp," %s(TTree *tree = 0);\n",classname);
fprintf(fp," ~%s() {;}\n",classname);
fprintf(fp," Int_t GetEvent(Int_t event);\n");
fprintf(fp," void Init(TTree *tree);\n");
fprintf(fp," void Loop();\n");
fprintf(fp," void Show(Int_t event = -1);\n");
fprintf(fp,"};\n");
fprintf(fp,"\n");
fprintf(fp,"#endif\n");
fprintf(fp,"\n");
fprintf(fp,"#ifdef %s_cxx\n",classname);
fprintf(fp,"\n");
// generate code for class constructor
fprintf(fp,"%s::%s(TTree *tree)\n",classname,classname);
fprintf(fp,"{\n");
fprintf(fp,"// if parameter tree is not specified (or zero), connect the file\n");
fprintf(fp,"// used to generate this class and read the Tree.\n");
fprintf(fp," if (tree == 0) {\n");
fprintf(fp," TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(\"%s\");\n",treefile);
fprintf(fp," if (!f) {\n");
fprintf(fp," f = new TFile(\"%s\");\n",treefile);
fprintf(fp," }\n");
fprintf(fp," tree = (TTree*)gDirectory->Get(\"%s\");\n\n",t->GetName());
fprintf(fp," }\n");
fprintf(fp," Init(tree);\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
// generate code for class member function GetEvent()
fprintf(fp,"Int_t %s::GetEvent(Int_t event)\n",classname);
fprintf(fp,"{\n");
fprintf(fp,"// Read specified event from the Tree into data members\n");
fprintf(fp," if (!fTree) return 0;\n");
fprintf(fp," // if (fEvent==event) return 1;\n");
nb = t->GetListOfBranches().GetEntriesFast();
for (i=0;i<nb;i++) {
branch = (TBranch*)t->GetListOfBranches().UncheckedAt(i);
fprintf(fp," branch_%s = 0;\n",branch->GetName());
}
fprintf(fp," fEvent = event;\n");
fprintf(fp," return 1;\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
// generate code for class member function Init()
fprintf(fp,"void %s::Init(TTree *tree)\n",classname);
fprintf(fp,"{\n");
fprintf(fp,"// Set branch addresses\n");
fprintf(fp," if (tree == 0) return;\n");
fprintf(fp," fTree = tree;\n");
for (l=0;l<nleaves;l++) {
TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
len = leaf->GetLen();
leafcount =leaf->GetLeafCount();
TBranch *branch = leaf->GetBranch();
if (leafcount) strcpy(branchname,branch->GetName());
else strcpy(branchname,leaf->GetTitle());
bname = branchname;
while (*bname) {if (*bname == '.') *bname='_'; bname++;}
char *brak = strstr(branchname,"[");
if (brak) *brak = 0;
head = headOK;
if (branch->IsA() == TBranchObject::Class()) {
if (branch->GetListOfBranches()->GetEntriesFast()) continue;
leafobj = (TLeafObject*)leaf;
if (!leafobj->GetClass()) head = headcom;
strcpy(branchname,branch->GetName());
}
if (leafcount) len = leafcount->GetMaximum()+1;
if (len > 1) fprintf(fp," %sfTree->SetBranchAddress(\"%s\",%s);\n",head,branch->GetName(),branchname);
else fprintf(fp," %sfTree->SetBranchAddress(\"%s\",&leaf_%s);\n",head,branch->GetName(),branchname);
}
fprintf(fp," fTree->SetBranchStatus(\"*\",0); // disable all branches\n");
nb = t->GetListOfBranches().GetEntriesFast();
for (i=0;i<nb;i++) {
branch = (TBranch*)t->GetListOfBranches().UncheckedAt(i);
fprintf(fp," branch_%s = 0;\n",branch->GetName());
fprintf(fp," branch_pointer_%s = fTree->GetBranch(\"%s\");\n",branch->GetName(),branch->GetName());
}
fprintf(fp," fEvent = -1;\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
// generate code for class member function Show()
fprintf(fp,"void %s::Show(Int_t event)\n",classname);
fprintf(fp,"{\n");
fprintf(fp,"// Print contents of event.\n");
fprintf(fp,"// If event is not specified, print current event\n");
fprintf(fp," if (!fTree) return;\n");
fprintf(fp," if (event>=0) fEvent = event;\n");
fprintf(fp," else event = fEvent;\n");
fprintf(fp," if (fEvent<0) return;\n");
fprintf(fp," fTree->SetBranchStatus(\"*\",1); // enable all branches\n");
fprintf(fp," fTree->Show(fEvent);\n");
fprintf(fp," fTree->SetBranchStatus(\"*\",0); // disable all branches\n");
nb = t->GetListOfBranches().GetEntriesFast();
for (i=0;i<nb;i++) {
branch = (TBranch*)t->GetListOfBranches().UncheckedAt(i);
fprintf(fp," branch_%s = 1;\n",branch->GetName());
}
fprintf(fp,"}\n");
fprintf(fp,"\n");
fprintf(fp,"#endif\n");
fprintf(fp,"\n");
//======================Generate classname.cxx=====================
// generate code for class member function Loop()
fprintf(fpc,"#ifndef %s_cxx\n",classname);
fprintf(fpc,"#define %s_cxx\n",classname);
fprintf(fpc,"#endif\n");
fprintf(fpc,"\n");
fprintf(fpc,"#include \"%s\"\n",thead);
fprintf(fpc,"\n");
fprintf(fpc,"#ifndef __CINT__\n");
fprintf(fpc,"// Place here all ROOT related includes that you need\n");
fprintf(fpc,"#endif\n");
fprintf(fpc,"\n");
fprintf(fpc,"void %s::Loop()\n",classname);
fprintf(fpc,"{\n");
fprintf(fpc,"\n// This is the loop skeleton\n");
fprintf(fpc," if (fTree == 0) return;\n");
fprintf(fpc,"\n Stat_t nentries = fTree->GetEntries();\n");
fprintf(fpc,"\n Int_t nbytes = 0, nb = 0;\n");
fprintf(fpc," for (Int_t i=0; i<nentries;i++) {\n");
fprintf(fpc," nb = fTree->GetEvent(i); nbytes += nb;\n");
fprintf(fpc," }\n");
fprintf(fpc,"}\n");
fprintf(fpc,"\n");
printf("Files: %s and %s generated from Tree: %s\n",thead,tcimp,t->GetName());
delete [] thead;
delete [] tcimp;
delete [] treefile;
fclose(fp);
fclose(fpc);
return 0;
}
//_____________________________________________________________________________
//////////////////////////////////////////////////////////
// This class has been automatically generated
// (Fri Apr 16 15:35:21 1999 by ROOT version 2.21/08)
// from TTree ntuple/Demo ntuple
// found on file: hsimple.root
//////////////////////////////////////////////////////////
#ifndef ntuple_hxx
#define ntuple_hxx
#ifndef __CINT__
#include "TROOT.h"
#include "TBranch.h"
#include "TTree.h"
#include "TFile.h"
#else
class TBranch;
class TTree;
class TFile;
#endif
class ntuple {
public :
TTree *fTree; //pointer to the analyzed TTree
Int_t fEvent; //current Event number
//Declaration of branches
Int_t branch_px;
TBranch *branch_pointer_px;
Int_t branch_py;
TBranch *branch_pointer_py;
Int_t branch_pz;
TBranch *branch_pointer_pz;
Int_t branch_random;
TBranch *branch_pointer_random;
Int_t branch_i;
TBranch *branch_pointer_i;
//Declaration of leaves
Float_t leaf_px;
Float_t &px() {if (branch_px) return leaf_px;branch_pointer_px->GetEvent(fEvent);branch_px = 1; return leaf_px;}
Float_t leaf_py;
Float_t &py() {if (branch_py) return leaf_py;branch_pointer_py->GetEvent(fEvent);branch_py = 1; return leaf_py;}
Float_t leaf_pz;
Float_t &pz() {if (branch_pz) return leaf_pz;branch_pointer_pz->GetEvent(fEvent);branch_pz = 1; return leaf_pz;}
Float_t leaf_random;
Float_t &random() {if (branch_random) return leaf_random;branch_pointer_random->GetEvent(fEvent);branch_random = 1; return leaf_random;}
Float_t leaf_i;
Float_t &i() {if (branch_i) return leaf_i;branch_pointer_i->GetEvent(fEvent);branch_i = 1; return leaf_i;}
ntuple(TTree *tree = 0);
~ntuple() {;}
Int_t GetEvent(Int_t event);
void Init(TTree *tree);
void Loop();
void Show(Int_t event = -1);
};
#endif
#ifdef ntuple_cxx
ntuple::ntuple(TTree *tree)
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
if (tree == 0) {
TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("hsimple.root");
if (!f) {
f = new TFile("hsimple.root");
}
tree = (TTree*)gDirectory->Get("ntuple");
}
Init(tree);
}
Int_t ntuple::GetEvent(Int_t event)
{
// Read specified event from the Tree into data members
if (!fTree) return 0;
// if (fEvent==event) return 1;
branch_px = 0;
branch_py = 0;
branch_pz = 0;
branch_random = 0;
branch_i = 0;
fEvent = event;
return 1;
}
void ntuple::Init(TTree *tree)
{
// Set branch addresses
if (tree == 0) return;
fTree = tree;
fTree->SetBranchAddress("px",&leaf_px);
fTree->SetBranchAddress("py",&leaf_py);
fTree->SetBranchAddress("pz",&leaf_pz);
fTree->SetBranchAddress("random",&leaf_random);
fTree->SetBranchAddress("i",&leaf_i);
fTree->SetBranchStatus("*",0); // disable all branches
branch_px = 0;
branch_pointer_px = fTree->GetBranch("px");
branch_py = 0;
branch_pointer_py = fTree->GetBranch("py");
branch_pz = 0;
branch_pointer_pz = fTree->GetBranch("pz");
branch_random = 0;
branch_pointer_random = fTree->GetBranch("random");
branch_i = 0;
branch_pointer_i = fTree->GetBranch("i");
fEvent = -1;
}
void ntuple::Show(Int_t event)
{
// Print contents of event.
// If event is not specified, print current event
if (!fTree) return;
if (event>=0) fEvent = event;
else event = fEvent;
if (fEvent<0) return;
fTree->SetBranchStatus("*",1); // enable all branches
fTree->Show(fEvent);
fTree->SetBranchStatus("*",0); // disable all branches
branch_px = 1;
branch_py = 1;
branch_pz = 1;
branch_random = 1;
branch_i = 1;
}
#endif
#ifndef ntuple_cxx
#define ntuple_cxx
#endif
#include "ntuple.hxx"
#ifndef __CINT__
// Place here all ROOT related includes that you need
#include "TH1.h"
#include "TH2.h"
#include "TCanvas.h"
#endif
void ntuple::Loop()
{
// This is the loop skeleton
if (fTree == 0) return;
TH1F *h_px= new TH1F("px","px",100,-4,4);
TH1F *h_py= new TH1F("py","py",100,-5,5);
TH1F *h_pz= new TH1F("pz","pz",100,0,20);
TH1F *h_random= new TH1F("random","random",100,0,1);
TH1F *h_i= new TH1F("i","i",100,0,30000);
TH2F *h_pxpz= new TH2F("pxpz","pxpz",100,0,20,100,-4,4);
Stat_t nentries = fTree->GetEntries();
Int_t nbytes = 0, nb = 0;
for (Int_t l=0; l<nentries;l++) {
nb = fTree->GetEvent(l); nbytes += nb;
h_px->Fill(px());
h_py->Fill(py());
h_pz->Fill(pz());
h_random->Fill(random());
h_i->Fill(i());
h_pxpz->Fill(pz(),px());
}
TCanvas *c = new TCanvas("c");
c->Divide(2,3);
c->cd(1);
h_px->Draw();
c->cd(2);
h_py->Draw();
c->cd(3);
h_pz->Draw();
c->cd(4);
h_random->Draw();
c->cd(5);
h_i->Draw();
c->cd(6);
h_pxpz->Draw();
}
SrcSuf = cxx
IncSuf = hxx
ObjSuf = o
ExeSuf =
DllSuf = so
OutPutOpt = -o
ROOTLIBS = -L$(ROOTSYS)/lib -lNew -lBase -lCint -lClib -lCont -lFunc \
-lGraf -lGraf3d -lHist -lHtml -lMatrix -lMeta -lMinuit -lNet \
-lPhysics -lPostscript -lProof -lTree -lUnix -lZip
ROOTGLIBS = -lGpad -lGui -lGX11 -lX3d
# Linux with egcs
EGCS = /opt/egcs/pro
CXX = g++
CXXFLAGS = -g -O2 -Wall -fno-rtti -fno-exceptions -fPIC -I$(ROOTSYS)/include
LD = g++
LDFLAGS = -g -O2 -Wl,-rpath,$(EGCS)/lib:$(ROOTSYS)/lib
SOFLAGS = -shared
LIBS = $(ROOTLIBS) -lm -ldl -rdynamic
GLIBS = $(ROOTLIBS) $(ROOTGLIBS) -L/usr/X11R6/lib \
-lXpm -lX11 -lm -ldl -rdynamic
#------------------------------------------------------------------------------
NTUPLEO = ntuple.$(ObjSuf) ntupleDict.$(ObjSuf)
NTUPLES = ntuple.$(SrcSuf) ntupleDict.$(SrcSuf)
NTUPLESO = ntuple.$(DllSuf)
OBJS = $(NTUPLEO)
PROGRAMS = $(NTUPLESO)
all: $(PROGRAMS)
$(NTUPLESO): $(NTUPLEO)
$(LD) $(SOFLAGS) $(LDFLAGS) $(NTUPLEO) $(OutPutOpt) $(NTUPLESO)
clean:
@rm -f $(OBJS) *Dict.* core
.SUFFIXES: .$(SrcSuf)
###
ntuple.$(ObjSuf): ntuple.$(SrcSuf) ntuple.$(IncSuf)
ntupleDict.$(SrcSuf): ntuple.$(IncSuf)
@echo "Generating dictionary ntupleDict..."
@$(ROOTSYS)/bin/rootcint -f ntupleDict.$(SrcSuf) -c ntuple.$(IncSuf)
.$(SrcSuf).$(ObjSuf):
$(CXX) $(CXXFLAGS) -c $<
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:31 MET