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 MakeClass macro possibly now works not only for trivial ntuples, but also for ntuples with arrays and other objects. Due to current CINT limitations ( as shipped with root 2.21/08 ), one cannot write 'x=leaf()[]; leaf()[]=y', one must say 'tmp=leaf(); x=tmp[]; tmp[]=y'. This was fixed in the development version of CINT, so the next root version should have it. Due to current CINT limitations one cannot use code generated by this macro for multi-dimensional arrays directly in CINT ( as a CINT macro ), one needs to compile the analysis code and create the shared library. Have fun, Jacek. P.S. The main difference to the previous version is a "bug" fix - the Loop() function called fTree->GetEvent() instead of it's own GetEvent() ( the same "bug" is present in the original TTree::MakeClass function ). To get rid of "fTree" in the Loop() I implemented also the GetEntries() function. On this occasion I noticed another "bug" ( "feature" ) of the TTree::GetEvent() function - in case ALL branches are "off" ( one set 'SetBranchStatus("*",0);' ) the TTree::GetEvent() reads the WHOLE event ( all branches !!! ). For me, in this case, it should read NOTHING. 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");) // - MakeClass(T,"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); // Prepare to fill t 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 \"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 *leaf_%s;\n",head,leafobj->GetTypeName(),leafobj->GetName()); fprintf(fp,"%s%-15s *%s() {",head,leafobj->GetTypeName(),leafobj->GetName()); fprintf(fp,"if (branch_%s) return leaf_%s;",branch->GetName(),leafobj->GetName()); fprintf(fp,"branch_pointer_%s->GetEvent(fEvent);",branch->GetName()); fprintf(fp,"branch_%s = 1;return leaf_%s;}\n",branch->GetName(),leafobj->GetName()); continue; } if (leafcount) { len = leafcount->GetMaximum(); if (twodim) { fprintf(fp," %-15s leaf_%s[%d]%s;\n",leaf->GetTypeName(),branchname,len,(char*)(twodim+1)); // fprintf(fp," %-15s (&%s())[%d]%s {",leaf->GetTypeName(),branchname,len,(char*)(twodim+1)); fprintf(fp," %-15s (*%s())%s {",leaf->GetTypeName(),branchname,(char*)(twodim+1)); 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); } else { fprintf(fp," %-15s leaf_%s[%d];\n",leaf->GetTypeName(),branchname,len); // fprintf(fp," %-15s (&%s())[%d] {",leaf->GetTypeName(),branchname,len); 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); } } 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); } } // Generate class member functions prototypes fprintf(fp,"\n"); fprintf(fp," %s(TTree *tree = 0);\n",classname); fprintf(fp," ~%s() {;}\n",classname); fprintf(fp," Stat_t GetEntries() {if (!fTree) return 0;return fTree->GetEntries();}\n"); 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," // Prepare to read specified event from the Tree.\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\",leaf_%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; 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,"#include \"%s\"\n",thead); fprintf(fpc,"#undef %s_cxx\n",classname); 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," // This is the loop skeleton.\n"); // fprintf(fpc,"\n if (fTree == 0) return;\n"); fprintf(fpc,"\n Stat_t nentries = GetEntries();\n"); fprintf(fpc,"\n Int_t ne = 0, nevents = 0;\n"); fprintf(fpc," for (Int_t i=0; i<nentries; i++) {\n"); fprintf(fpc," ne = GetEvent(i); nevents += ne;\n"); fprintf(fpc," \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 23 18:57:27 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 "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() {;} Stat_t GetEntries() {if (!fTree) return 0;return fTree->GetEntries();} 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) { // Prepare to read specified event from the Tree. 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" #undef ntuple_cxx #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. 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 = GetEntries(); Int_t ne = 0, nevents = 0; for (Int_t l=0; l<nentries; l++) { ne = GetEvent(l); nevents += ne; 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:32 MET