Hi, This is the second part of my MakeClass suite. Please find attached some example files generated by the new version of my MakeClass suite for the $ROOTSYS/tutorials/hsimple.root file. First, if you are using emacs, please find attached an emacs.rc.add ( some code to be placed in your private .emacs file ) which gives you outline/folding editor settings to be used with both the MakeClass.cxx itself, and with files generated by this macro ( try "EmacsMenu -> Hide -> Hide Body" or C-c @ C-t and enjoy ). Then, some notes on how to use the generated skeleton analysis : 1. You can use the ntuple.[hc]xx directly in root ( as a CINT macro ) : root > .L ntuple.cxx root > ntuple *n = new ntuple() or, you can build the shared library ntuple.so ( an example Makefile for Linux is also attached ), and then : root > .L ntuple.so root > ntuple *n = new ntuple() The second method is preferred, as it gives much better performance. 2. You can "hardcode" your analysis into the ntuple::Loop() function, as in the example file ntuple.cxx, but this makes the problem, that whenever you need to make any small change in it, you need to "reload" the whole analysis ( including creating a new shared library, if you use this method ) : root > .L ntuple.so // or ".L ntuple.cxx" root > ntuple *n = new ntuple() root > n->Loop() 3. You can leave the ntuple::Loop() function EMPTY ( you won't need it later ) and create the ntuple.so ONCE. Then you can copy the ntuple.cxx into the loop.cxx, and modify the ntuple::Loop() skeleton ( in loop.cxx file ) to be an "Int_t loop(ntuple *)" function, and later you can : root > .L ntuple.so root > ntuple *n = new ntuple() root > .L loop.cxx root > loop(n) or simply : root > .L ntuple.so root > ntuple *n = new ntuple() root > .x loop.cxx(n) Note, whenever you change anything in your analysis "loop" you only need to reload the ".L loop.cxx", no changes to the shared library ntuple.so are required ( you get the full compiled code speed in accessing your ntuple mixed with CINT flexibility ). An example loop.cxx is also attached. 4. Last, but not least, there is an automatically generated function : Int_t ntuple::Loop(Int_t (*analysis)(ntuple *)) which loops over all entries and for every entry calls the given "Int_t analysis(ntuple *)" function which is expected to analyse the current ( single ) entry. And again, you can mix compiled ntuple.so ( created ONCE ) with interpreted "analysis" : root > .L ntuple.so root > ntuple *n = new ntuple() root > .L analysis.cxx root > n->Loop(analysis) Note again, whenever you change anything in your "analysis", you only need to reload the ".L analysis.cxx", no changes to the shared library ntuple.so are required. An example analysis.cxx is also attached. Warning : CINT shipped with root 2.21/08 has some problems with this method, but the new CINT, starting with root 2.22/04, works well. Have fun, Jacek. ;;;; ;;;; minor mode: column (autoload 'display-column-mode "column" nil t) (display-column-mode 1) ;;;; (load "paren") ; automatic parenthesis matching library ;;;; ;;;; ... load the cc-mode mode ... (autoload 'c++-mode "cc-mode" "C++ Editing Mode" t) (autoload 'c-mode "cc-mode" "C Editing Mode" t) (autoload 'objc-mode "cc-mode" "Objective-C Editing Mode" t) ;;;; ... to be used with c++, c and objective-c files (setq auto-mode-alist (append '(("\\.C$" . c++-mode) ("\\.H$" . c++-mode) ("\\.cc$" . c++-mode) ("\\.hh$" . c++-mode) ("\\.c$" . c-mode) ("\\.h$" . c-mode) ("\\.m$" . objc-mode) ) auto-mode-alist)) ;;;; ;;;; My C and C++ outline-minor-mode settings ( Jacek M. Holeczek 1999 ). ;;;; ;;;; Outline mode headings are lines of C and C++ source code which contain, ;;;; at any position, C or C++ commentary headings ( that is `/*' or `//' ) ;;;; followed by one or more asterisk, hash or underscore characters ( mixing ;;;; of them is allowed ) : one character for major headings, two characters ;;;; for subheadings, etc., optionally followed by a (sub)heading description ;;;; ( see `my-c-c++-outline-regexp' and `my-c-c++-outline-level' below ). ;;;; All other C and C++ source code lines are body lines. ;;;; ;;(defvar my-c-c++-outline-regexp ;; "^.*/[\*/][ \t]*\\(\\)[\*#_]+\\([ \t]+.*$\\|$\\)") ;;(defun my-c-c++-outline-level () ;; (save-excursion ;; (looking-at outline-regexp) ;; (- (match-beginning 2) (match-end 1)))) ;;;; ;;;; Outline mode headings are lines of C and C++ source code which in the ;;;; beginning, not counting leading white space characters, contain C or ;;;; C++ commentary headings ( that is `/*' or `//' ) followed by one or ;;;; more asterisk, hash or underscore characters ( the count of these ;;;; characters does not matter, mixing of them is allowed ), optionally ;;;; followed by a (sub)heading description. The heading's nesting level is ;;;; calculated from the indentation of the C or C++ commentary ( see ;;;; `my-c-c++-outline-regexp' and `my-c-c++-outline-level' below ). ;;;; All other C and C++ source code lines are body lines. ;;;; (defvar my-c-c++-outline-regexp "^[ \t]*\\(\\)/[\*/][ \t]*[\*#_]+\\([ \t]+.*$\\|$\\)") (defun my-c-c++-outline-level () (save-excursion (looking-at outline-regexp) (string-width (buffer-substring (match-beginning 0) (match-end 1))))) ;;;; ;;;; Also the foldout.el is automatically loaded. It provides folding editor ;;;; extensions and mouse bindings for entering and exiting folds and for ;;;; showing and hiding text ( Meta-Control-Down-Mouse-{1,2,3} - see the ;;;; foldout.el source code for details ). ;;;; (add-hook 'c-mode-hook (function (lambda () (setq outline-regexp my-c-c++-outline-regexp) (setq outline-level 'my-c-c++-outline-level) (outline-minor-mode 1) (require 'foldout)))) (add-hook 'c++-mode-hook (function (lambda () (setq outline-regexp my-c-c++-outline-regexp) (setq outline-level 'my-c-c++-outline-level) (outline-minor-mode 1) (require 'foldout)))) ;;;; ;;;; End of my C and C++ outline-minor-mode settings. ;;;; ;;;; Highlighting by font-lock.el mode. (global-font-lock-mode t) (setq font-lock-support-mode 'lazy-lock-mode) (setq font-lock-maximum-decoration t) ;;;; // # // # This class has been automatically generated // # (Tue Jun 15 10:43:23 1999 by ROOT version 2.22/04) // # from TTree ntuple/Demo ntuple // # found on file: hsimple.root // # // # *** The ntuple class interface *** #ifndef ntuple_hxx #define ntuple_hxx // # Required includes #ifndef __CINT__ #include <stdio.h> #include <stream.h> #include "TROOT.h" #include "TTree.h" #include "TFile.h" #include "Api.h" #else class TBranch; class TTree; class TFile; #endif // # class ntuple class ntuple { public: // # public variables TTree *fTree; // pointer to the analysed TTree Int_t fEntry; // current entry number // # declaration of branches and leaves // branch px Int_t IsRead_px; TBranch *b_px; Float_t l_px; Float_t &px() {if (IsRead_px) return l_px;b_px->GetEntry(fEntry);IsRead_px=1;return l_px;} // branch py Int_t IsRead_py; TBranch *b_py; Float_t l_py; Float_t &py() {if (IsRead_py) return l_py;b_py->GetEntry(fEntry);IsRead_py=1;return l_py;} // branch pz Int_t IsRead_pz; TBranch *b_pz; Float_t l_pz; Float_t &pz() {if (IsRead_pz) return l_pz;b_pz->GetEntry(fEntry);IsRead_pz=1;return l_pz;} // branch random Int_t IsRead_random; TBranch *b_random; Float_t l_random; Float_t &random() {if (IsRead_random) return l_random;b_random->GetEntry(fEntry);IsRead_random=1;return l_random;} // branch i Int_t IsRead_i; TBranch *b_i; Float_t l_i; Float_t &i() {if (IsRead_i) return l_i;b_i->GetEntry(fEntry);IsRead_i=1;return l_i;} // # public functions ntuple(Char_t *filename = 0); ntuple(TTree *tree) {if (!tree) ntuple();else Init(tree);} ~ntuple() {;} Stat_t GetEntries() {if (!fTree) return 0;return fTree->GetEntries();} Int_t GetEntry(Int_t entry); void Init(TTree *tree); Int_t Loop(); Int_t Loop(Int_t (*analysis)(ntuple *)); void Show(Int_t entry = -1); }; #endif // # *** The ntuple class implementation *** #ifdef ntuple_cxx // # ntuple::ntuple(Char_t *filename) ntuple::ntuple(Char_t *filename) { // # If parameter filename is not specified (or zero), connect the file // # used to generate this class ( hsimple.root ). if (!filename || !(*filename)) { filename = "hsimple.root"; } // # Find the required file in ROOT and, if not found, open it. TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename); if (!f) { f = new TFile(filename); } // # Find the ntuple tree and initialize object. TTree *t = (TTree*)gDirectory->Get("ntuple"); Init(t); } // # Int_t ntuple::GetEntry(Int_t entry) Int_t ntuple::GetEntry(Int_t entry) { // # Prepare to read specified entry from the Tree. // # In case the entry is already read, just return. if (!fTree) return 0; if (fEntry==entry) return 1; fEntry = entry; // # Set branch statuses to 0. IsRead_px = 0; IsRead_py = 0; IsRead_pz = 0; IsRead_random = 0; IsRead_i = 0; // # We are done, return. return 1; } // # void ntuple::Init(TTree *tree) void ntuple::Init(TTree *tree) { // # Initialize public variables. fTree = tree; fEntry = -1; if (!tree) return; // # Set branch statuses to 0, get branch pointers, // # set branch addresses. fTree->SetBranchStatus("*",1); // enable all branches // branch px IsRead_px = 0; b_px = fTree->GetBranch("px"); b_px->SetAddress(&l_px); // branch py IsRead_py = 0; b_py = fTree->GetBranch("py"); b_py->SetAddress(&l_py); // branch pz IsRead_pz = 0; b_pz = fTree->GetBranch("pz"); b_pz->SetAddress(&l_pz); // branch random IsRead_random = 0; b_random = fTree->GetBranch("random"); b_random->SetAddress(&l_random); // branch i IsRead_i = 0; b_i = fTree->GetBranch("i"); b_i->SetAddress(&l_i); } // # Int_t ntuple::Loop(Int_t (*analysis)(ntuple *)) Int_t ntuple::Loop(Int_t (*analysis)(ntuple *)) { // # Execute the analysis function for every entry. In case the // # analysis function returns a non zero value, break the loop. if (!fTree || !analysis) return 0; // # Local variables ( common to compiled and interpreted code ). Stat_t nentries = GetEntries(); // Number of entries in the Tree. Int_t ientries = 0; // How many entries were analysed. // # This is the entry loop in compiled code. #ifndef __CINT__ // # First define some local variables and objects. char temp[64]; // INTERPRETEDFUNC long offset = 0; // INTERPRETEDFUNC G__ClassInfo globalscope; // INTERPRETEDFUNC G__CallFunc func; // INTERPRETEDFUNC, COMPILEDINTERFACEMETHOD, BYTECODEFUNC // # Then execute the loop. switch(G__isinterpretedp2f(((void*)analysis))) { // # using function call as string case G__INTERPRETEDFUNC: sprintf(temp,"(ntuple *)%p",(void*)this); func.SetFunc(&globalscope,(char*)analysis,temp,&offset); for (Int_t i=0; i<nentries; i++) { ientries += GetEntry(i); if (func.ExecInt((void*)NULL)) break; } break; // # using interface method case G__COMPILEDINTERFACEMETHOD: func.SetFunc((G__InterfaceMethod)analysis); func.SetArg(((long)this)); for (Int_t i=0; i<nentries; i++) { ientries += GetEntry(i); if (func.ExecInt((void*)NULL)) break; } break; // # bytecode version of interpreted func case G__BYTECODEFUNC: func.SetBytecode((struct G__bytecodefunc*)analysis); func.SetArg(((long)this)); for (Int_t i=0; i<nentries; i++) { ientries += GetEntry(i); if (func.ExecInt((void*)NULL)) break; } break; // # using true pointer to function case G__COMPILEDTRUEFUNC: // # pointer not in CINT global function table case G__UNKNOWNFUNC: for (Int_t i=0; i<nentries; i++) { ientries += GetEntry(i); if ((*analysis)(this)) break; } break; // # this should never happen ( unknown kind of pointer ) default: cerr << "Error : Unknown kind of pointer to function" << endl; break; } // # This is the entry loop in interpreted code. #else // # current CINT cannot deal with this #if 0 for (Int_t i=0; i<nentries; i++) { ientries += GetEntry(i); if ((*analysis)(this)) break; // current CINT cannot deal with it } // # so we need to use this #else Int_t result; for (Int_t i=0; i<nentries; i++) { ientries += GetEntry(i); result = (*analysis)(this); if (result) break; } #endif #endif // # We are done, return. return ientries; } // # void ntuple::Show(Int_t entry) void ntuple::Show(Int_t entry) { // # Print contents of entry ( all branches ). // # If entry is not specified, print current entry. if (!fTree) return; if (entry>=0) fEntry = entry; else entry = fEntry; if (fEntry<0) return; // # Set branch statuses to 1. fTree->SetBranchStatus("*",1); // enable all branches IsRead_px = 1; IsRead_py = 1; IsRead_pz = 1; IsRead_random = 1; IsRead_i = 1; // # Show entry. fTree->Show(fEntry); } #endif // # End of file ntuple.hxx // # Include the ntuple class interface specification. #ifndef ntuple_cxx #define ntuple_cxx #endif #include "ntuple.hxx" #undef ntuple_cxx // # Place here all ROOT related includes that you need. #ifndef __CINT__ #include "TH1.h" #include "TH2.h" #include "TCanvas.h" #endif // # Int_t ntuple::Loop() Int_t ntuple::Loop() { // # Local variables. Stat_t nentries = GetEntries(); // Number of entries in the Tree. Int_t ientries = 0; // How many entries were analysed. // # Create histograms. 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); // # This is the loop skeleton. for (Int_t l=0; l<nentries; l++) { ientries += GetEntry(l); 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()); } // # Show results. 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(); // # We are done, return. return ientries; } // # End of file ntuple.cxx 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 $< 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 -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 $< // # Place here all ROOT related includes that you need. #ifndef __CINT__ #include "ntuple.hxx" // Include the ntuple class interface specification. #include "TH1.h" #include "TH2.h" #include "TCanvas.h" #else class ntuple; #endif // # Int_t loop(ntuple *n) Int_t loop(ntuple *n) { // # Local variables. Stat_t nentries = n->GetEntries(); // Number of entries in the Tree. Int_t ientries = 0; // How many entries were analysed. // # Create histograms. 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); // # This is the loop skeleton. for (Int_t l=0; l<nentries; l++) { ientries += n->GetEntry(l); h_px->Fill(n->px()); h_py->Fill(n->py()); h_pz->Fill(n->pz()); h_random->Fill(n->random()); h_i->Fill(n->i()); h_pxpz->Fill(n->pz(),n->px()); } // # Show results. 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(); // # We are done, return. return ientries; } // # End of file loop.cxx // # Place here all ROOT related includes that you need. #ifndef __CINT__ #include "ntuple.hxx" // Include the ntuple class interface specification. #include "TH1.h" #include "TH2.h" #include "TCanvas.h" #else class ntuple; #endif // # Create histograms. 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); // # Int_t analysis(ntuple *n) Int_t analysis(ntuple *n) { // # Analyse single ( current ) entry. h_px->Fill(n->px()); h_py->Fill(n->py()); h_pz->Fill(n->pz()); h_random->Fill(n->random()); h_i->Fill(n->i()); h_pxpz->Fill(n->pz(),n->px()); // # We are done, return. return 0; } // # End of file analysis.cxx
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:34 MET