RooCFunction4Binding.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  *    File: $Id: RooCFunction4Binding.h 36207 2010-10-08 19:00:29Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, NIKHEF, verkerke@nikhef.nl                         *
00007  *                                                                           *
00008  * Copyright (c) 2000-2008, NIKHEF, Regents of the University of California  *
00009  *                          and Stanford University. All rights reserved.    *
00010  *                                                                           *
00011  *****************************************************************************/
00012 
00013 #ifndef ROOCFUNCTION4BINDING
00014 #define ROOCFUNCTION4BINDING
00015 
00016 #include "TString.h"
00017 #include "RooAbsReal.h"
00018 #include "RooAbsPdf.h"
00019 #include "RooRealProxy.h"
00020 #include "RooMsgService.h"
00021 #include <string>
00022 #include <map>
00023 #include <vector>
00024 
00025 namespace RooFit {
00026 
00027 typedef Double_t (*CFUNCD4DDDD)(Double_t,Double_t,Double_t,Double_t) ;
00028 typedef Double_t (*CFUNCD4DDDI)(Double_t,Double_t,Double_t,Int_t) ;
00029 typedef Double_t (*CFUNCD4DDDB)(Double_t,Double_t,Double_t,Bool_t) ;
00030 
00031 RooAbsReal* bindFunction(const char* name,void* func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
00032 RooAbsPdf* bindPdf(const char* name,void* func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
00033 #ifndef __CINT__
00034 RooAbsReal* bindFunction(const char* name,CFUNCD4DDDD func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
00035 RooAbsReal* bindFunction(const char* name,CFUNCD4DDDI func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
00036 RooAbsReal* bindFunction(const char* name,CFUNCD4DDDB func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
00037 RooAbsPdf* bindPdf(const char* name,CFUNCD4DDDD func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
00038 RooAbsPdf* bindPdf(const char* name,CFUNCD4DDDI func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
00039 RooAbsPdf* bindPdf(const char* name,CFUNCD4DDDB func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
00040 #endif
00041 
00042 }
00043 
00044 
00045 template<class VO, class VI1, class VI2, class VI3, class VI4>
00046 class RooCFunction4Map {
00047  public:
00048   RooCFunction4Map() {} ;
00049 
00050   void add(const char* name, VO (*ptr)(VI1,VI2,VI3,VI4), const char* arg1name="x", const char* arg2name="y",
00051                                                          const char* arg3name="z", const char* arg4name="w") {
00052     // Register function with given name and argument name
00053     _ptrmap[name] = ptr ;
00054     _namemap[ptr] = name ;
00055     _argnamemap[ptr].push_back(arg1name) ;
00056     _argnamemap[ptr].push_back(arg2name) ;
00057     _argnamemap[ptr].push_back(arg3name) ;
00058     _argnamemap[ptr].push_back(arg4name) ;
00059   }
00060 
00061 
00062   const char* lookupName(VO (*ptr)(VI1,VI2,VI3,VI4)) {
00063     // Return name of function given by pointer
00064     return _namemap[ptr].c_str() ;
00065   }
00066 
00067   VO (*lookupPtr(const char* name))(VI1,VI2,VI3,VI4) {
00068     // Return pointer of function given by name
00069     return _ptrmap[name] ;
00070   }
00071 
00072   const char* lookupArgName(VO (*ptr)(VI1,VI2,VI3,VI4), UInt_t iarg) {
00073     // Return name of i-th argument of function. If function is
00074     // not registered, argument names 0,1,2 are x,y,z
00075     if (iarg<_argnamemap[ptr].size()) {
00076       return (_argnamemap[ptr])[iarg].c_str() ;
00077     }
00078     switch (iarg) {
00079     case 0: return "x" ;
00080     case 1: return "y" ;
00081     case 2: return "z" ;
00082     case 3: return "w" ;
00083     }
00084     return "v" ;
00085   }
00086 
00087  private:
00088 
00089 #ifndef __CINT__
00090   std::map<std::string,VO (*)(VI1,VI2,VI3,VI4)> _ptrmap ; // Pointer-to-name map
00091   std::map<VO (*)(VI1,VI2,VI3,VI4),std::string> _namemap ; // Name-to-pointer map
00092   std::map<VO (*)(VI1,VI2,VI3,VI4),std::vector<std::string> > _argnamemap ; // Pointer-to-argnamelist map
00093 #endif
00094 } ;
00095 
00096 
00097 
00098 template<class VO, class VI1, class VI2, class VI3, class VI4>
00099 class RooCFunction4Ref : public TObject {
00100  public:
00101   RooCFunction4Ref(VO (*ptr)(VI1,VI2,VI3,VI4)=0) : _ptr(ptr) {
00102     // Constructor of persistable function reference
00103   } ;
00104   ~RooCFunction4Ref() {} ;
00105 
00106   VO operator()(VI1 x,VI2 y,VI3 z,VI4 w) const {
00107     // Evaluate embedded function
00108     return (*_ptr)(x,y,z,w) ;
00109   }
00110 
00111   const char* name() const {
00112     // Return registered name of embedded function. If function
00113     // is not registered return string with hex presentation
00114     // of function pointer value
00115     const char* result = fmap().lookupName(_ptr) ;
00116     if (result && strlen(result)) {
00117       return result ;
00118     }
00119     // This union is to avoid a warning message:
00120     union { 
00121        void *_ptr;
00122        func_t _funcptr;
00123     } temp;
00124     temp._funcptr = _ptr;
00125     return Form("(%p)",temp._ptr) ;
00126   }
00127 
00128   const char* argName(Int_t iarg) {
00129     // Return suggested name for i-th argument
00130     return fmap().lookupArgName(_ptr,iarg) ;
00131   }
00132 
00133   static RooCFunction4Map<VO,VI1,VI2,VI3,VI4>& fmap() {
00134     // Return reference to function pointer-to-name mapping service
00135     if (!_fmap) {
00136       _fmap = new RooCFunction4Map<VO,VI1,VI2,VI3,VI4> ;
00137     }
00138     return *_fmap ;
00139   }
00140  private:
00141 
00142   static VO dummyFunction(VI1,VI2,VI3,VI4) {
00143     // Dummy function used when registered function was not
00144     // found in un-persisting object
00145     return 0 ;
00146   }
00147 
00148 
00149   typedef VO (*func_t)(VI1,VI2,VI3,VI4);
00150   func_t _ptr; //! Pointer to embedded function
00151 
00152   static RooCFunction4Map<VO,VI1,VI2,VI3,VI4>* _fmap ; // Pointer to mapping service object
00153 
00154   ClassDef(RooCFunction4Ref,1) // Persistable reference to C function pointer
00155 } ;
00156 
00157 
00158 
00159 template<class VO, class VI1, class VI2, class VI3, class VI4>
00160 void RooCFunction4Ref<VO,VI1,VI2,VI3,VI4>::Streamer(TBuffer &R__b)
00161 {
00162   // Custom streamer for function pointer reference object. When writing,
00163   // the function pointer is substituted by its registerd name. When function
00164   // is unregistered name 'UNKNOWN' is written and a warning is issues. When
00165   // reading back, the embedded name is converted back to a function pointer
00166   // using the mapping service. When name UNKNOWN is encountered a warning is
00167   // issues and a dummy null function is substituted. When the registered function
00168   // name can not be mapped to a function pointer an ERROR is issued and a pointer
00169   // to the dummy null function is substituted
00170 
00171   typedef ::RooCFunction4Ref<VO,VI1,VI2,VI3,VI4> thisClass;
00172 
00173    // Stream an object of class RooCFunction4Ref
00174    if (R__b.IsReading()) {
00175 
00176      UInt_t R__s, R__c;
00177      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00178 
00179      // Read name from file
00180      TString tmpName ;
00181      tmpName.Streamer(R__b) ;
00182 
00183      if (tmpName=="UNKNOWN" && R__v>0) {
00184 
00185        coutW(ObjectHandling) << "WARNING: Objected embeds function pointer to unknown function, object will not be functional" << endl ;
00186        _ptr = dummyFunction ;
00187 
00188      } else {
00189 
00190        // Lookup pointer to C function wih given name
00191        _ptr = fmap().lookupPtr(tmpName.Data()) ;
00192 
00193        if (_ptr==0) {
00194          coutW(ObjectHandling) << "ERROR: Objected embeds pointer to function named " << tmpName
00195                                << " but no such function is registered, object will not be functional" << endl ;
00196        }
00197      }
00198 
00199 
00200      R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
00201 
00202    } else {
00203 
00204      UInt_t R__c;
00205      R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
00206 
00207      // Lookup name of reference C function
00208      TString tmpName = fmap().lookupName(_ptr) ;
00209      if (tmpName.Length()==0) {
00210        coutW(ObjectHandling) << "WARNING: Cannot persist unknown function pointer " << Form("0x%lx",(ULong_t)_ptr)
00211                              << " written object will not be functional when read back" <<  endl ;
00212        tmpName="UNKNOWN" ;
00213      }
00214 
00215      // Persist the name
00216      tmpName.Streamer(R__b) ;
00217 
00218      R__b.SetByteCount(R__c, kTRUE);
00219 
00220    }
00221 }
00222 
00223 
00224 
00225 template<class VO,class VI1, class VI2, class VI3, class VI4>
00226 class RooCFunction4Binding : public RooAbsReal {
00227 public:
00228   RooCFunction4Binding() {
00229     // Default constructor
00230   } ;
00231   RooCFunction4Binding(const char *name, const char *title, VO (*_func)(VI1,VI2,VI3,VI4), RooAbsReal& _x, RooAbsReal& _y, RooAbsReal& _z, RooAbsReal& _w);
00232   RooCFunction4Binding(const RooCFunction4Binding& other, const char* name=0) ;
00233   virtual TObject* clone(const char* newname) const { return new RooCFunction4Binding(*this,newname); }
00234   inline virtual ~RooCFunction4Binding() { }
00235 
00236   void printArgs(ostream& os) const {
00237     // Print object arguments and name/address of function pointer
00238     os << "[ function=" << func.name() << " " ;
00239     for (Int_t i=0 ; i<numProxies() ; i++) {
00240       RooAbsProxy* p = getProxy(i) ;
00241       if (!TString(p->name()).BeginsWith("!")) {
00242         p->print(os) ;
00243         os << " " ;
00244       }
00245     }
00246     os << "]" ;
00247   }
00248 
00249 protected:
00250 
00251   RooCFunction4Ref<VO,VI1,VI2,VI3,VI4> func ; // Function pointer reference
00252   RooRealProxy x ;              // Argument reference
00253   RooRealProxy y ;              // Argument reference
00254   RooRealProxy z ;              // Argument reference
00255   RooRealProxy w ;              // Argument reference
00256 
00257   Double_t evaluate() const {
00258     // Return value of embedded function using value of referenced variable x
00259     return func(x,y,z,w) ;
00260   }
00261 
00262 private:
00263 
00264   ClassDef(RooCFunction4Binding,1) // RooAbsReal binding to external C functions
00265 };
00266 
00267 
00268 template<class VO,class VI1, class VI2, class VI3, class VI4>
00269 RooCFunction4Binding<VO,VI1,VI2,VI3,VI4>::RooCFunction4Binding(const char *name, const char *title, VO (*_func)(VI1,VI2,VI3,VI4),
00270                                                        RooAbsReal& _x, RooAbsReal& _y, RooAbsReal& _z, RooAbsReal& _w) :
00271   RooAbsReal(name,title),
00272   func(_func),
00273   x(func.argName(0),func.argName(0),this,_x),
00274   y(func.argName(1),func.argName(1),this,_y),
00275   z(func.argName(2),func.argName(2),this,_z),
00276   w(func.argName(3),func.argName(3),this,_w)
00277 {
00278   // Constructor of C function binding object given a pointer to a function and a RooRealVar to which the function
00279   // argument should be bound. This object is fully functional as a RooFit function object. The only restriction is
00280   // if the referenced function is _not_ a standard ROOT TMath or MathCore function it can not be persisted in a
00281   // a RooWorkspace
00282 }
00283 
00284 
00285 template<class VO,class VI1, class VI2, class VI3, class VI4>
00286 RooCFunction4Binding<VO,VI1,VI2,VI3,VI4>::RooCFunction4Binding(const RooCFunction4Binding& other, const char* name) :
00287   RooAbsReal(other,name),
00288   func(other.func),
00289   x("x",this,other.x),
00290   y("y",this,other.y),
00291   z("z",this,other.z),
00292   w("w",this,other.w)
00293 {
00294   // Copy constructor
00295 }
00296 
00297 
00298 template<class VO,class VI1, class VI2, class VI3, class VI4>
00299 class RooCFunction4PdfBinding : public RooAbsPdf {
00300 public:
00301   RooCFunction4PdfBinding() {
00302     // Default constructor
00303   } ;
00304   RooCFunction4PdfBinding(const char *name, const char *title, VO (*_func)(VI1,VI2,VI3,VI4), RooAbsReal& _x, RooAbsReal& _y, RooAbsReal& _z, RooAbsReal& _w);
00305   RooCFunction4PdfBinding(const RooCFunction4PdfBinding& other, const char* name=0) ;
00306   virtual TObject* clone(const char* newname) const { return new RooCFunction4PdfBinding(*this,newname); }
00307   inline virtual ~RooCFunction4PdfBinding() { }
00308 
00309   void printArgs(ostream& os) const {
00310     // Print object arguments and name/address of function pointer
00311     os << "[ function=" << func.name() << " " ;
00312     for (Int_t i=0 ; i<numProxies() ; i++) {
00313       RooAbsProxy* p = getProxy(i) ;
00314       if (!TString(p->name()).BeginsWith("!")) {
00315         p->print(os) ;
00316         os << " " ;
00317       }
00318     }
00319     os << "]" ;
00320   }
00321 
00322 protected:
00323 
00324   RooCFunction4Ref<VO,VI1,VI2,VI3,VI4> func ; // Function pointer reference
00325   RooRealProxy x ;              // Argument reference
00326   RooRealProxy y ;              // Argument reference
00327   RooRealProxy z ;              // Argument reference
00328   RooRealProxy w ;              // Argument reference
00329 
00330   Double_t evaluate() const {
00331     // Return value of embedded function using value of referenced variable x
00332     return func(x,y,z,w) ;
00333   }
00334 
00335 private:
00336 
00337   ClassDef(RooCFunction4PdfBinding,1) // RooAbsReal binding to external C functions
00338 };
00339 
00340 
00341 template<class VO,class VI1, class VI2, class VI3, class VI4>
00342 RooCFunction4PdfBinding<VO,VI1,VI2,VI3,VI4>::RooCFunction4PdfBinding(const char *name, const char *title, VO (*_func)(VI1,VI2,VI3,VI4),
00343                                                        RooAbsReal& _x, RooAbsReal& _y, RooAbsReal& _z, RooAbsReal& _w) :
00344   RooAbsPdf(name,title),
00345   func(_func),
00346   x(func.argName(0),func.argName(0),this,_x),
00347   y(func.argName(1),func.argName(1),this,_y),
00348   z(func.argName(2),func.argName(2),this,_z),
00349   w(func.argName(3),func.argName(3),this,_w)
00350 {
00351   // Constructor of C function binding object given a pointer to a function and a RooRealVar to which the function
00352   // argument should be bound. This object is fully functional as a RooFit function object. The only restriction is
00353   // if the referenced function is _not_ a standard ROOT TMath or MathCore function it can not be persisted in a
00354   // a RooWorkspace
00355 }
00356 
00357 
00358 template<class VO,class VI1, class VI2, class VI3, class VI4>
00359 RooCFunction4PdfBinding<VO,VI1,VI2,VI3,VI4>::RooCFunction4PdfBinding(const RooCFunction4PdfBinding& other, const char* name) :
00360   RooAbsPdf(other,name),
00361   func(other.func),
00362   x("x",this,other.x),
00363   y("y",this,other.y),
00364   z("z",this,other.z),
00365   w("w",this,other.w)
00366 {
00367   // Copy constructor
00368 }
00369 
00370 #endif

Generated on Tue Jul 5 14:26:06 2011 for ROOT_528-00b_version by  doxygen 1.5.1