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