RooCFunction1Binding.h

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

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