added user function API example

This commit is contained in:
nemu 2008-06-04 05:47:15 +00:00
parent a0a6c86a91
commit 56b872222f
11 changed files with 747 additions and 0 deletions

View File

@ -0,0 +1,95 @@
#---------------------------------------------------
# Makefile
#
# Author: Andreas Suter
# e-mail: andreas.suter@psi.ch
#
# $Id$
#---------------------------------------------------
#---------------------------------------------------
# get compilation and library flags from root-config
ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags)
ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs)
ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs)
#---------------------------------------------------
# depending on the architecture, choose the compiler,
# linker, and the flags to use
#
OSTYPE = linux
ifeq ($(OSTYPE),linux)
OS = LINUX
endif
ifeq ($(OSTYPE),linux-gnu)
OS = LINUX
endif
ifeq ($(OSTYPE),darwin)
OS = DARWIN
endif
# -- Linux
ifeq ($(OS),LINUX)
CXX = g++
CXXFLAGS = -g -Wall -fPIC
INCLUDES = -I ./
LD = g++
LDFLAGS = -g
endif
# -- Darwin
ifeq ($(OS),DARWIN)
CXX = g++
CXXFLAGS = -g -Wall -fPIC
INCLUDES = -I../include
LD = g++
LDFLAGS = -g
endif
# the output from the root-config script:
CXXFLAGS += $(ROOTCFLAGS)
LDFLAGS +=
# the ROOT libraries (G = graphic)
LIBS = $(ROOTLIBS) -lXMLParser
GLIBS = $(ROOTGLIBS) -lXMLParser
# UserFcn lib
USERFCNLIB = -lTUserFcnBase -lTUserFcn
INSTALLPATH = ./
EXEC = userFcnTest
# some definitions: headers, sources, objects,...
OBJS =
OBJS += $(EXEC).o
# make the executable:
#
all: $(EXEC)
$(EXEC): $(OBJS)
@echo "---> Building $(EXEC) ..."
/bin/rm -f $(SHLIB)
$(LD) $(OBJS) -o $(EXEC) $(LIBS) $(USERFCNLIB)
@echo "done"
# clean up: remove all object file (and core files)
# semicolon needed to tell make there is no source
# for this target!
#
clean:; @rm -f $(OBJS)
@echo "---> removing $(OBJS)"
#
$(OBJS): %.o: %.cpp
$(CXX) $(INCLUDES) $(CXXFLAGS) -c $<
install: all
@echo "copy $(EXEC) to $(INSTALLPATH)"
cp -p $(EXEC) $(INSTALLPATH)

View File

@ -0,0 +1,97 @@
#---------------------------------------------------
# Makefile.TUserFcn
#
# Author: Andreas Suter
# e-mail: andreas.suter@psi.ch
#
# $Id$
#
#---------------------------------------------------
#---------------------------------------------------
# get compilation and library flags from root-config
ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags)
ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs)
ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs)
#---------------------------------------------------
# depending on the architecture, choose the compiler,
# linker, and the flags to use
#
ifeq ($(OSTYPE),linux)
OS = LINUX
endif
ifeq ($(OSTYPE),linux-gnu)
OS = LINUX
endif
ifeq ($(OSTYPE),darwin)
OS = DARWIN
endif
# -- Linux
ifeq ($(OS),LINUX)
CXX = g++
CXXFLAGS = -g -Wall -Wno-trigraphs -fPIC
INCLUDES = -I./
LD = g++
LDFLAGS = -g
SOFLAGS = -O -shared
endif
# -- Darwin
ifeq ($(OS),DARWIN)
CXX = g++
CXXFLAGS = -g -Wall -Wno-trigraphs -fPIC
INCLUDES = -I../include
LD = g++
LDFLAGS = -g
SOFLAGS = -dynamic
endif
# the output from the root-config script:
CXXFLAGS += $(ROOTCFLAGS)
LDFLAGS +=
# the ROOT libraries (G = graphic)
LIBS = $(ROOTLIBS) -lXMLParser
GLIBS = $(ROOTGLIBS) -lXMLParser
# some definitions: headers (used to generate *Dict* stuff), sources, objects,...
OBJS =
OBJS += TUserFcn.o TUserFcnDict.o
SHLIB = libTUserFcn.so
# make the shared lib:
#
all: $(SHLIB)
$(SHLIB): $(OBJS)
@echo "---> Building shared library $(SHLIB) ..."
/bin/rm -f $(SHLIB)
$(LD) $(OBJS) $(SOFLAGS) -o $(SHLIB) $(LIBS)
@echo "done"
# clean up: remove all object file (and core files)
# semicolon needed to tell make there is no source
# for this target!
#
clean:; @rm -f $(OBJS) *Dict* core*
@echo "---> removing $(OBJS)"
#
$(OBJS): %.o: %.cpp
$(CXX) $(INCLUDES) $(CXXFLAGS) -c $<
TUserFcnDict.cpp: TUserFcn.h TUserFcnLinkDef.h
@echo "Generating dictionary $@..."
rootcint -f $@ -c -p $^
install: all
@echo "Installing shared lib: libTUserFcn.so ( you must be root ;-) )"
ifeq ($(OS),LINUX)
cp -pv $(SHLIB) $(ROOTSYS)/lib
cp -pv TUserFcn.h $(ROOTSYS)/include
endif

View File

@ -0,0 +1,97 @@
#---------------------------------------------------
# Makefile.TUserFcnBase
#
# Author: Andreas Suter
# e-mail: andreas.suter@psi.ch
#
# $Id$
#
#---------------------------------------------------
#---------------------------------------------------
# get compilation and library flags from root-config
ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags)
ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs)
ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs)
#---------------------------------------------------
# depending on the architecture, choose the compiler,
# linker, and the flags to use
#
ifeq ($(OSTYPE),linux)
OS = LINUX
endif
ifeq ($(OSTYPE),linux-gnu)
OS = LINUX
endif
ifeq ($(OSTYPE),darwin)
OS = DARWIN
endif
# -- Linux
ifeq ($(OS),LINUX)
CXX = g++
CXXFLAGS = -g -Wall -Wno-trigraphs -fPIC
INCLUDES = -I./
LD = g++
LDFLAGS = -g
SOFLAGS = -O -shared
endif
# -- Darwin
ifeq ($(OS),DARWIN)
CXX = g++
CXXFLAGS = -g -Wall -Wno-trigraphs -fPIC
INCLUDES = -I../include
LD = g++
LDFLAGS = -g
SOFLAGS = -dynamic
endif
# the output from the root-config script:
CXXFLAGS += $(ROOTCFLAGS)
LDFLAGS +=
# the ROOT libraries (G = graphic)
LIBS = $(ROOTLIBS) -lXMLParser
GLIBS = $(ROOTGLIBS) -lXMLParser
# some definitions: headers (used to generate *Dict* stuff), sources, objects,...
OBJS =
OBJS += TUserFcnBase.o TUserFcnBaseDict.o
SHLIB = libTUserFcnBase.so
# make the shared lib:
#
all: $(SHLIB)
$(SHLIB): $(OBJS)
@echo "---> Building shared library $(SHLIB) ..."
/bin/rm -f $(SHLIB)
$(LD) $(OBJS) $(SOFLAGS) -o $(SHLIB) $(LIBS)
@echo "done"
# clean up: remove all object file (and core files)
# semicolon needed to tell make there is no source
# for this target!
#
clean:; @rm -f $(OBJS) *Dict* core*
@echo "---> removing $(OBJS)"
#
$(OBJS): %.o: %.cpp
$(CXX) $(INCLUDES) $(CXXFLAGS) -c $<
TUserFcnBaseDict.cpp: TUserFcnBase.h TUserFcnBaseLinkDef.h
@echo "Generating dictionary $@..."
rootcint -f $@ -c -p $^
install: all
@echo "Installing shared lib: libTUserFcn.so ( you must be root ;-) )"
ifeq ($(OS),LINUX)
cp -pv $(SHLIB) $(ROOTSYS)/lib
cp -pv TUserFcn.h $(ROOTSYS)/include
endif

52
src/tests/userFcn/README Normal file
View File

@ -0,0 +1,52 @@
/***************************************************************************
README
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
**Overview**
The collection of files here demonstrate how to implement a plugin
mechanism for a user function, i.e. also loading classes at runtime.
For a discussion see also
http://root.cern.ch/phpBB2/viewtopic.php?p=28117#28117
The idea is that a main program has an interface such that specific
user functions can be added without recompiling the main. Therefore
class identification at runtime are needed. This is possible in root
via the dictionary mechanism and the class TClass.
**Description of the files and their purposes**
The class TUserFcnBase is "almost pure virtual" and only needed to define
an interface of a user function. This is needed to efficiently call
the function at runtime.
The class TUserFcn ist the implementation of the user function.
userFcnTest is the main demonstrating how to invoke all the necessary
objects, how to cast them, and how to execute the wanted user function.
* Makefiles:
userFcnTest.cpp, main to demonstrate how to use a user function
TUserFcnBase.h interface definition for the user function including
TUserFcnBaseLinkDef.h a dictionary
TUserFcnBase.cpp
TUserFcn.h implementaion class of the user function including
TUserFcnLinkDef.h a dictionary
TUserFcn.cpp
Makefile, will generate userFcnTest
Makefile.TUserFcnBase, will generate the shared library libUserFcnBase
needed for runtime loading of the user function
Makefile.TUserFcn, will generate the shared library libUserFcn
needed for runtime loading of the user function

View File

@ -0,0 +1,95 @@
/***************************************************************************
TUserFcn.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <iostream>
using namespace std;
#include <cassert>
#include "TUserFcn.h"
ClassImp(TUserFcn)
//------------------------------------------------------
/**
*
*/
TUserFcn::TUserFcn()
{
}
//------------------------------------------------------
/**
*
*/
TUserFcn::~TUserFcn()
{
}
//------------------------------------------------------
/**
*
*/
Double_t TUserFcn::Eval(Double_t t, const std::vector<Double_t> &param) const
{
/*
cout << endl << ">> Eval: t=" << t << ", param=";
for (unsigned int i=0; i<param.size(); i++) {
cout << param[i];
if (i<param.size()-1)
cout << ", ";
}
cout << endl << endl;
*/
assert(param.size() >= 3);
return param[0] + param[1]*t + param[2]*t*t;
}
//------------------------------------------------------
/**
*
*/
Double_t TUserFcn::operator()(Double_t t, const std::vector<Double_t> &param) const
{
/*
cout << endl << ">> Eval: t=" << t << ", param=";
for (unsigned int i=0; i<param.size(); i++) {
cout << param[i];
if (i<param.size()-1)
cout << ", ";
}
cout << endl << endl;
*/
assert(param.size() >= 3);
return param[0] + param[1]*t + param[2]*t*t;
}

View File

@ -0,0 +1,51 @@
/***************************************************************************
TUserFcn.h
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef _TUSERFCN_H_
#define _TUSERFCN_H_
#include <vector>
#include "TUserFcnBase.h"
class TUserFcn : public TUserFcnBase
{
public:
TUserFcn();
~TUserFcn();
Double_t Eval(Double_t t, const std::vector<Double_t> &param) const;
Double_t operator()(Double_t t, const std::vector<Double_t> &param) const;
ClassDef(TUserFcn, 1)
};
#endif // _TUSERFCN_H_

View File

@ -0,0 +1,50 @@
/***************************************************************************
TUserFcnBase.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "TUserFcnBase.h"
ClassImp(TUserFcnBase)
//------------------------------------------------------
/**
*
*/
TUserFcnBase::TUserFcnBase()
{
}
//------------------------------------------------------
/**
*
*/
TUserFcnBase::~TUserFcnBase()
{
}

View File

@ -0,0 +1,51 @@
/***************************************************************************
TUserFcnBase.h
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef _TUSERFCNBASE_H_
#define _TUSERFCNBASE_H_
#include <vector>
#include <TObject.h>
class TUserFcnBase : public TObject
{
public:
TUserFcnBase();
virtual ~TUserFcnBase();
virtual Double_t Eval(Double_t t, const std::vector<Double_t> &param) const = 0;
virtual Double_t operator()(Double_t t, const std::vector<Double_t> &param) const = 0;
ClassDef(TUserFcnBase, 1)
};
#endif // _TUSERFCNBASE_H_

View File

@ -0,0 +1,40 @@
/***************************************************************************
TUserFcnBaseLinkDef.h
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class TUserFcnBase+;
#endif

View File

@ -0,0 +1,9 @@
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class TUserFcn+;
#endif

View File

@ -0,0 +1,110 @@
/***************************************************************************
userFcnTest.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <sys/time.h>
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
#include <TApplication.h>
#include <TClass.h>
#include <TString.h>
#include <TTime.h>
#include "TUserFcnBase.h"
Double_t func(Double_t t, const std::vector<Double_t> &param)
{
assert(param.size() >= 3);
return param[0] + param[1]*t + param[2]*t*t;
}
int main(int argc, char *argv[])
{
// check if class is found (argv[1] == class name)
if (!TClass::GetDict("TUserFcn")) {
cout << endl << "**ERROR**: user function class 'TUserFcn' not found.";
cout << endl << endl;
return 0;
}
// generate class object
TUserFcnBase *obj = (TUserFcnBase*)TClass::GetClass("TUserFcn")->New();
if (obj == 0) {
cout << endl << "**ERROR**: couldn't invoke user function class 'TUserFcn'.";
cout << endl << endl;
return 0;
}
// prepare input for the TUserFcn::Eval
Double_t t = 0.1;
vector<Double_t> param;
param.push_back(0.23);
param.push_back(0.76);
param.push_back(2.55);
param.push_back(8.87);
Double_t retValue = 0.0;
struct timeval tv1, tv2;
gettimeofday(&tv1, 0);
for (unsigned int i=0; i<1e4; i++) {
if (i==0)
cout << endl << ">> obj->Eval(t, param) = " << obj->Eval(t, param);
obj->Eval(t, param);
}
gettimeofday(&tv2, 0);
double dt1 = tv2.tv_sec * 1000.0 + tv2.tv_usec / 1000.0 - (tv1.tv_sec * 1000.0 + tv1.tv_usec / 1000.0);
gettimeofday(&tv1, 0);
for (unsigned int i=0; i<1e4; i++) {
if (i==0)
cout << endl << ">> func(t, param) = " << func(t, param);
retValue = func(t, param);
}
gettimeofday(&tv2, 0);
double dt2 = tv2.tv_sec * 1000.0 + tv2.tv_usec / 1000.0 - (tv1.tv_sec * 1000.0 + tv1.tv_usec / 1000.0);
cout << endl << ">> dt1 = " << dt1 << " (ms), dt2 = " << dt2 << " (ms), retValue = " << retValue;
cout << endl << endl;
// clean up
param.clear();
if (obj) {
delete obj;
obj = 0;
}
return 0;
}