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