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