RooCFunction3Binding.h

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

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