ROOT  6.06/09
Reference Guide
RooCFunction2Binding.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * File: $Id$
5  * Authors: *
6  * WV, Wouter Verkerke, NIKHEF, verkerke@nikhef.nl *
7  * *
8  * Copyright (c) 2000-2008, NIKHEF, Regents of the University of California *
9  * and Stanford University. All rights reserved. *
10  * *
11  *****************************************************************************/
12 
13 #ifndef ROOCFUNCTION2BINDING
14 #define ROOCFUNCTION2BINDING
15 
16 #include "TString.h"
17 #include "RooAbsReal.h"
18 #include "RooAbsPdf.h"
19 #include "RooRealProxy.h"
20 #include "RooMsgService.h"
21 #include <string>
22 #include <map>
23 #include <vector>
24 
25 namespace RooFit {
26 
32 
33 
39 RooAbsPdf* bindPdf(const char* name,CFUNCD2DD func,RooAbsReal& x, RooAbsReal& y) ;
40 RooAbsPdf* bindPdf(const char* name,CFUNCD2ID func,RooAbsReal& x, RooAbsReal& y) ;
41 RooAbsPdf* bindPdf(const char* name,CFUNCD2UD func,RooAbsReal& x, RooAbsReal& y) ;
42 RooAbsPdf* bindPdf(const char* name,CFUNCD2DI func,RooAbsReal& x, RooAbsReal& y) ;
43 RooAbsPdf* bindPdf(const char* name,CFUNCD2II func,RooAbsReal& x, RooAbsReal& y) ;
44 
45 }
46 
47 template<class VO, class VI1, class VI2>
49  public:
51 
52  void add(const char* name, VO (*ptr)(VI1,VI2), const char* arg1name="x", const char* arg2name="y") {
53  // Register function with given name and argument name
54  _ptrmap[name] = ptr ;
55  _namemap[ptr] = name ;
56  _argnamemap[ptr].push_back(arg1name) ;
57  _argnamemap[ptr].push_back(arg2name) ;
58  }
59 
60 
61  const char* lookupName(VO (*ptr)(VI1,VI2)) {
62  // Return name of function given by pointer
63  return _namemap[ptr].c_str() ;
64  }
65 
66  VO (*lookupPtr(const char* name))(VI1,VI2) {
67  // Return pointer of function given by name
68  return _ptrmap[name] ;
69  }
70 
71  const char* lookupArgName(VO (*ptr)(VI1,VI2), UInt_t iarg) {
72  // Return name of i-th argument of function. If function is
73  // not registered, argument names 0,1,2 are x,y,z
74  if (iarg<_argnamemap[ptr].size()) {
75  return (_argnamemap[ptr])[iarg].c_str() ;
76  }
77  switch (iarg) {
78  case 0: return "x" ;
79  case 1: return "y" ;
80  case 2: return "z" ;
81  }
82  return "w" ;
83  }
84 
85  private:
86 
87 #ifndef __CINT__
88  std::map<std::string,VO (*)(VI1,VI2)> _ptrmap ; // Pointer-to-name map
89  std::map<VO (*)(VI1,VI2),std::string> _namemap ; // Name-to-pointer map
90  std::map<VO (*)(VI1,VI2),std::vector<std::string> > _argnamemap ; // Pointer-to-argnamelist map
91 #endif
92 } ;
93 
94 
95 
96 template<class VO, class VI1, class VI2>
97 class RooCFunction2Ref : public TObject {
98  public:
99  RooCFunction2Ref(VO (*ptr)(VI1,VI2)=0) : _ptr(ptr) {
100  // Constructor of persistable function reference
101  } ;
103 
104  VO operator()(VI1 x,VI2 y) const {
105  // Evaluate embedded function
106  return (*_ptr)(x,y) ;
107  }
108 
109  const char* name() const {
110  // Return registered name of embedded function. If function
111  // is not registered return string with hex presentation
112  // of function pointer value
113  const char* result = fmap().lookupName(_ptr) ;
114  if (result && strlen(result)) {
115  return result ;
116  }
117  // This union is to avoid a warning message:
118  union {
119  void *_ptr;
120  func_t _funcptr;
121  } temp;
122  temp._funcptr = _ptr;
123  return Form("(%p)",temp._ptr) ;
124  }
125 
126  const char* argName(Int_t iarg) {
127  // Return suggested name for i-th argument
128  return fmap().lookupArgName(_ptr,iarg) ;
129  }
130 
132  // Return reference to function pointer-to-name mapping service
133  if (!_fmap) {
135  }
136  return *_fmap ;
137  }
138 
139  private:
140 
141  static VO dummyFunction(VI1,VI2) {
142  // Dummy function used when registered function was not
143  // found in un-persisting object
144  return 0 ;
145  }
146 
147  typedef VO (*func_t)(VI1,VI2);
148  func_t _ptr; //! Pointer to embedded function
149 
150  static RooCFunction2Map<VO,VI1,VI2>* _fmap ; // Pointer to mapping service object
151 
152  ClassDef(RooCFunction2Ref,1) // Persistable reference to C function pointer
153 } ;
154 
155 
156 
157 template<class VO, class VI1, class VI2>
159 {
160  // Custom streamer for function pointer reference object. When writing,
161  // the function pointer is substituted by its registerd name. When function
162  // is unregistered name 'UNKNOWN' is written and a warning is issues. When
163  // reading back, the embedded name is converted back to a function pointer
164  // using the mapping service. When name UNKNOWN is encountered a warning is
165  // issues and a dummy null function is substituted. When the registered function
166  // name can not be mapped to a function pointer an ERROR is issued and a pointer
167  // to the dummy null function is substituted
168 
169  typedef ::RooCFunction2Ref<VO,VI1,VI2> thisClass;
170 
171  // Stream an object of class RooCFunction2Ref
172  if (R__b.IsReading()) {
173 
174  UInt_t R__s, R__c;
175  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
176 
177  // Read name from file
178  TString tmpName ;
179  tmpName.Streamer(R__b) ;
180 
181  if (tmpName=="UNKNOWN" && R__v>0) {
182 
183  coutW(ObjectHandling) << "WARNING: Objected embeds function pointer to unknown function, object will not be functional" << std::endl ;
184  _ptr = dummyFunction ;
185 
186  } else {
187 
188  // Lookup pointer to C function wih given name
189  _ptr = fmap().lookupPtr(tmpName.Data()) ;
190 
191  if (_ptr==0) {
192  coutW(ObjectHandling) << "ERROR: Objected embeds pointer to function named " << tmpName
193  << " but no such function is registered, object will not be functional" << std::endl ;
194  }
195  }
196 
197 
198  R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
199 
200  } else {
201 
202  UInt_t R__c;
203  R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
204 
205  // Lookup name of reference C function
206  TString tmpName = fmap().lookupName(_ptr) ;
207  if (tmpName.Length()==0) {
208  coutW(ObjectHandling) << "WARNING: Cannot persist unknown function pointer " << Form("0x%lx", (ULong_t)_ptr)
209  << " written object will not be functional when read back" << std::endl ;
210  tmpName="UNKNOWN" ;
211  }
212 
213  // Persist the name
214  tmpName.Streamer(R__b) ;
215 
216  R__b.SetByteCount(R__c, kTRUE);
217 
218  }
219 }
220 
221 
222 
223 template<class VO,class VI1, class VI2>
225 public:
227  // Default constructor
228  } ;
229  RooCFunction2Binding(const char *name, const char *title, VO (*_func)(VI1,VI2), RooAbsReal& _x, RooAbsReal& _y);
230  RooCFunction2Binding(const RooCFunction2Binding& other, const char* name=0) ;
231  virtual TObject* clone(const char* newname) const { return new RooCFunction2Binding(*this,newname); }
232  inline virtual ~RooCFunction2Binding() { }
233 
234  void printArgs(std::ostream& os) const {
235  // Print object arguments and name/address of function pointer
236  os << "[ function=" << func.name() << " " ;
237  for (Int_t i=0 ; i<numProxies() ; i++) {
238  RooAbsProxy* p = getProxy(i) ;
239  if (!TString(p->name()).BeginsWith("!")) {
240  p->print(os) ;
241  os << " " ;
242  }
243  }
244  os << "]" ;
245  }
246 
247 protected:
248 
249  RooCFunction2Ref<VO,VI1,VI2> func ; // Function pointer reference
250  RooRealProxy x ; // Argument reference
251  RooRealProxy y ; // Argument reference
252 
253  Double_t evaluate() const {
254  // Return value of embedded function using value of referenced variable x
255  return func(x,y) ;
256  }
257 
258 private:
259 
260  ClassDef(RooCFunction2Binding,1) // RooAbsReal binding to external C functions
261 };
262 
263 template<class VO,class VI1, class VI2>
264 RooCFunction2Binding<VO,VI1,VI2>::RooCFunction2Binding(const char *name, const char *title, VO (*_func)(VI1,VI2),
265  RooAbsReal& _x, RooAbsReal& _y) :
266  RooAbsReal(name,title),
267  func(_func),
268  x(func.argName(0),func.argName(0),this,_x),
269  y(func.argName(1),func.argName(1),this,_y)
270 {
271  // Constructor of C function binding object given a pointer to a function and a RooRealVar to which the function
272  // argument should be bound. This object is fully functional as a RooFit function object. The only restriction is
273  // if the referenced function is _not_ a standard ROOT TMath or MathCore function it can not be persisted in a
274  // a RooWorkspace
275 }
276 
277 
278 template<class VO,class VI1, class VI2>
280  RooAbsReal(other,name),
281  func(other.func),
282  x("x",this,other.x),
283  y("y",this,other.y)
284 {
285  // Copy constructor
286 }
287 
288 
289 
290 
291 template<class VO,class VI1, class VI2>
293 public:
295  // Default constructor
296  } ;
297  RooCFunction2PdfBinding(const char *name, const char *title, VO (*_func)(VI1,VI2), RooAbsReal& _x, RooAbsReal& _y);
298  RooCFunction2PdfBinding(const RooCFunction2PdfBinding& other, const char* name=0) ;
299  virtual TObject* clone(const char* newname) const { return new RooCFunction2PdfBinding(*this,newname); }
300  inline virtual ~RooCFunction2PdfBinding() { }
301 
302  void printArgs(std::ostream& os) const {
303  // Print object arguments and name/address of function pointer
304  os << "[ function=" << func.name() << " " ;
305  for (Int_t i=0 ; i<numProxies() ; i++) {
306  RooAbsProxy* p = getProxy(i) ;
307  if (!TString(p->name()).BeginsWith("!")) {
308  p->print(os) ;
309  os << " " ;
310  }
311  }
312  os << "]" ;
313  }
314 
315 protected:
316 
317  RooCFunction2Ref<VO,VI1,VI2> func ; // Function pointer reference
318  RooRealProxy x ; // Argument reference
319  RooRealProxy y ; // Argument reference
320 
321  Double_t evaluate() const {
322  // Return value of embedded function using value of referenced variable x
323  return func(x,y) ;
324  }
325 
326 private:
327 
328  ClassDef(RooCFunction2PdfBinding,1) // RooAbsReal binding to external C functions
329 };
330 
331 template<class VO,class VI1, class VI2>
332 RooCFunction2PdfBinding<VO,VI1,VI2>::RooCFunction2PdfBinding(const char *name, const char *title, VO (*_func)(VI1,VI2),
333  RooAbsReal& _x, RooAbsReal& _y) :
334  RooAbsPdf(name,title),
335  func(_func),
336  x(func.argName(0),func.argName(0),this,_x),
337  y(func.argName(1),func.argName(1),this,_y)
338 {
339  // Constructor of C function binding object given a pointer to a function and a RooRealVar to which the function
340  // argument should be bound. This object is fully functional as a RooFit function object. The only restriction is
341  // if the referenced function is _not_ a standard ROOT TMath or MathCore function it can not be persisted in a
342  // a RooWorkspace
343 }
344 
345 
346 template<class VO,class VI1, class VI2>
348  RooAbsPdf(other,name),
349  func(other.func),
350  x("x",this,other.x),
351  y("y",this,other.y)
352 {
353  // Copy constructor
354 }
355 
356 #endif
Double_t evaluate() const
virtual void print(std::ostream &os, Bool_t addContents=kFALSE) const
Print proxy name.
Definition: RooAbsProxy.cxx:74
RooCFunction2Ref< VO, VI1, VI2 > func
Bool_t IsReading() const
Definition: TBuffer.h:81
short Version_t
Definition: RtypesCore.h:61
Ssiz_t Length() const
Definition: TString.h:390
RooAbsPdf * bindPdf(const char *name, CFUNCD1D func, RooAbsReal &x)
RooCFunction2Map< double, int, double > * _fmap
const char * lookupArgName(VO(*ptr)(VI1, VI2), UInt_t iarg)
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
RooCFunction2Ref(VO(*ptr)(VI1, VI2)=0)
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
RooCFunction2Ref< VO, VI1, VI2 > func
#define coutW(a)
Definition: RooMsgService.h:34
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
RooAbsProxy * getProxy(Int_t index) const
Return the nth proxy from the proxy list.
Definition: RooAbsArg.cxx:1253
RooAbsReal * bindFunction(const char *name, CFUNCD1D func, RooAbsReal &x)
const char * Data() const
Definition: TString.h:349
void printArgs(std::ostream &os) const
Print object arguments, ie its proxies.
Double_t x[n]
Definition: legend1.C:17
#define ClassDef(name, id)
Definition: Rtypes.h:254
virtual TObject * clone(const char *newname) const
static RooCFunction2Map< VO, VI1, VI2 > * _fmap
Pointer to embedded function.
bool BeginsWith(const std::string &theString, const std::string &theSubstring)
const char * argName(Int_t iarg)
Double_t(* CFUNCD2II)(Int_t, Int_t)
void add(const char *name, VO(*ptr)(VI1, VI2), const char *arg1name="x", const char *arg2name="y")
static RooCFunction2Map< VO, VI1, VI2 > & fmap()
Double_t(* CFUNCD2UD)(UInt_t, Double_t)
Int_t numProxies() const
Return the number of registered proxies.
Definition: RooAbsArg.cxx:1266
TClass * IsA() const
unsigned int UInt_t
Definition: RtypesCore.h:42
char * Form(const char *fmt,...)
std::map< VO(*)(VI1, VI2), std::string > _namemap
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
std::map< VO(*)(VI1, VI2), std::vector< std::string > > _argnamemap
const char * name() const
Double_t(* CFUNCD2DD)(Double_t, Double_t)
virtual const char * name() const
Definition: RooAbsProxy.h:42
double Double_t
Definition: RtypesCore.h:55
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
unsigned long ULong_t
Definition: RtypesCore.h:51
Double_t(* CFUNCD2DI)(Double_t, Int_t)
Double_t(* CFUNCD2ID)(Int_t, Double_t)
Double_t y[n]
Definition: legend1.C:17
double func(double *x, double *p)
Definition: stressTF1.cxx:213
#define name(a, b)
Definition: linkTestLib0.cpp:5
Mother of all ROOT objects.
Definition: TObject.h:58
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
void printArgs(std::ostream &os) const
Print object arguments, ie its proxies.
std::map< std::string, VO(*)(VI1, VI2)> _ptrmap
virtual TObject * clone(const char *newname) const
VO(* func_t)(VI1, VI2)
static VO dummyFunction(VI1, VI2)
VO operator()(VI1 x, VI2 y) const
double result[121]
VO(*)(VI1, VI2) lookupPtr(const char *name)
const char * lookupName(VO(*ptr)(VI1, VI2))
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0