MakeClass ( 8 3/4 )

From: Jacek M. Holeczek (holeczek@us.edu.pl)
Date: Fri May 21 1999 - 10:23:06 MEST


Hi,
Please find attached some example files generated by the new version of my
MakeClass suite for the $ROOTSYS/tutorials/hsimple.root file.
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 events and for every event calls the given
   "Int_t analysis(ntuple *)" function which is expected to analyze the
   current ( single ) event. 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 : current CINT, as shiped with root 2.21/08 has some problems
   with this method, you probably need to wait till the new root 2.22 is
   out which has the new CINT in 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.


// # 
// # This class has been automatically generated 
// # (Thu May 20 20:23:25 1999 by ROOT version 2.21/08) 
// # 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           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;}
  
  // # 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 GetEvent(Int_t event);
  void Init(TTree *tree);
  Int_t Loop();
  Int_t Loop(Int_t (*analysis)(ntuple *));
  void Show(Int_t event = -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::GetEvent(Int_t event) 
Int_t ntuple::GetEvent(Int_t event)
{
  // # Prepare to read specified event from the Tree. 
  if (!fTree) return 0;
  fEvent = event;
  // # Set branch statuses to 0 
  branch_px = 0;
  branch_py = 0;
  branch_pz = 0;
  branch_random = 0;
  branch_i = 0;
  return 1;
}

// # void ntuple::Init(TTree *tree) 
void ntuple::Init(TTree *tree)
{
  // # Initialize public variables. 
  fTree = tree;
  fEvent = -1;
  if (!tree) return;
  // # Set branch addresses. 
  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);
  // # Set branch statuses to 0, initialize branch pointers 
  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");
}

// # Int_t ntuple::Loop(Int_t (*analysis)(ntuple *)) 
Int_t ntuple::Loop(Int_t (*analysis)(ntuple *))
{
  // # Execute the analysis function for every event. 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 nevents = 0; // How many events were analysed.
  
  // # This is the event 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++) {
      nevents += GetEvent(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++) {
      nevents += GetEvent(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++) {
      nevents += GetEvent(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++) {
      nevents += GetEvent(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 event loop in interpreted code. 
#else
  
  // # current CINT cannot deal with this 
#if 0
  for (Int_t i=0; i<nentries; i++) {
    nevents += GetEvent(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++) {
    nevents += GetEvent(i);
    result = (*analysis)(this);
    if (result) break;
  }
#endif
  
#endif
  
  // # We are done, return. 
  return nevents;
}

// # void ntuple::Show(Int_t event) 
void ntuple::Show(Int_t event)
{
  // # Print contents of event ( all branches ). 
  // # 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
  // # Set branch statuses to 1 
  branch_px = 1;
  branch_py = 1;
  branch_pz = 1;
  branch_random = 1;
  branch_i = 1;
}

#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 nevents = 0; // How many events 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++) {
    nevents += GetEvent(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 nevents;
}

// # 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 $<

// # 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 nevents = 0; // How many events 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++) {
    nevents += n->GetEvent(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 nevents;
}

// # 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 event. 
  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:33 MET