Instead of writing C++ macros which are intepreted by CINT, one can think of adding a class to ROOT itself. This may be particularly useful for methods that draw and save histograms, apply cuts, etc. The advantage over macros is the stability, as the code is compiled and then executed, and not interpreted by CINT.
Suppose you want to write a (simple) class with a method that creates a ROOT file. You need the following three files: ana.cc, ana.hh and a Makefile.
Your .cc file should look somehow like this:
#include "ana.hh" using namespace std; ClassImp(ana) // ----------------------------------------------------- // Constructor // ----------------------------------------------------- ana::ana() { cout << "This is the AnalysisClass, v 1.0" << endl; } // ------------------------------------------------------ // Destructor // ------------------------------------------------------ ana::~ana(){ } // ---------------------------------------- // test // ---------------------------------------- void ana::test(){ TFile *bla = new TFile("bla.root","CREATE"); }
Your .hh file should look like:
#ifndef ANA #define ANA #include <TObject.h> #include <TFile.h> #include <TF1.h> #include <TROOT.h> class ana: public TObject { public: ana(); ~ana(); void test(); ClassDef(ana,1) }; #endif
The Makefile should look like this:
# =============================== # Makefile for ana # =============================== ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) CXX = g++ CXXFLAGS = -g -Wall -fPIC SOFLAGS = -shared CXXFLAGS += $(ROOTCFLAGS) ANACLASSES = ana.o anaDict.o # =============================== ana: ana.cc # ------------------------------- $(CXX) $(CXXFLAGS) -c ana.cc -o ana.o $(ROOTSYS)/bin/rootcint -f anaDict.cc -c ana.hh $(CXX) $(CXXFLAGS) -c anaDict.cc -o anaDict.o $(CXX) $(SOFLAGS) $(ANACLASSES) -o libAnaClasses.so $(ROOTGLIBS) # =============================== clean: rm -f ana.o anaDict.o anaDict.cc anaDict.h libAnaClasses.so # ===============================
make
in your directory, you should have five new files: ana.o, anaDict.cc, anaDict.h, anaDict.o and libAnaClasses.so. .L libAnaClasses.so
. You can write a Logon script for ROOT that will do this for you.ana myanaclass
.myanaclass.test()
. Now you should have successfully created a ROOT file named bla.root.symbol lookup error … undefined symbol: _ZN5TFile4OpenEPKcS1_S1_ii
, this may have several reasons:$ROOTSYS
is set (echo $ROOTSYS
) and if yes, check if the path of ROOT is the same as in $LD_LIBRARY_PATH
and $PATH
. If you have setup Gaudi and DaVinci, these things should be correct. Otherwise you have to add setenv ROOTSYS /afs/cern.ch/sw/lcg/external/root/5.18.00d/slc4_amd64_gcc34/root
(depends on your preferred ROOT version and on your architecture) and
setenv LD_LIBRARY_PATH $ROOTSYS/lib:$LD_LIBRARY_PATH setenv PATH $ROOTSYS/bin:$PATH
in your .tcshrc file (if you are working on a tcsh).
-lRooFit
for the GLIBSThe original articles about the addition of a class to ROOT are provided here.