Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/root/RooCFunction4Binding.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*****************************************************************************
0002  * Project: RooFit                                                           *
0003  * Package: RooFitCore                                                       *
0004  *    File: $Id$
0005  * Authors:                                                                  *
0006  *   WV, Wouter Verkerke, NIKHEF, verkerke@nikhef.nl                         *
0007  *                                                                           *
0008  * Copyright (c) 2000-2008, NIKHEF, Regents of the University of California  *
0009  *                          and Stanford University. All rights reserved.    *
0010  *                                                                           *
0011  *****************************************************************************/
0012 
0013 #ifndef ROOCFUNCTION4BINDING
0014 #define ROOCFUNCTION4BINDING
0015 
0016 #include "RooAbsReal.h"
0017 #include "RooAbsPdf.h"
0018 #include "RooRealProxy.h"
0019 #include "RooMsgService.h"
0020 
0021 #include "TBuffer.h"
0022 #include "TString.h"
0023 
0024 #include <string>
0025 #include <map>
0026 #include <vector>
0027 
0028 namespace RooFit {
0029 
0030 typedef double (*CFUNCD4DDDD)(double,double,double,double) ;
0031 typedef double (*CFUNCD4DDDI)(double,double,double,Int_t) ;
0032 typedef double (*CFUNCD4DDDB)(double,double,double,bool) ;
0033 
0034 RooAbsReal* bindFunction(const char* name,CFUNCD4DDDD func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
0035 RooAbsReal* bindFunction(const char* name,CFUNCD4DDDI func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
0036 RooAbsReal* bindFunction(const char* name,CFUNCD4DDDB func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
0037 RooAbsPdf* bindPdf(const char* name,CFUNCD4DDDD func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
0038 RooAbsPdf* bindPdf(const char* name,CFUNCD4DDDI func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
0039 RooAbsPdf* bindPdf(const char* name,CFUNCD4DDDB func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
0040 
0041 }
0042 
0043 
0044 template<class VO, class VI1, class VI2, class VI3, class VI4>
0045 class RooCFunction4Map {
0046  public:
0047   RooCFunction4Map() {} ;
0048 
0049   void add(const char* name, VO (*ptr)(VI1,VI2,VI3,VI4), const char* arg1name="x", const char* arg2name="y",
0050                                                        const char* arg3name="z", const char* arg4name="w") {
0051     // Register function with given name and argument name
0052     _ptrmap[name] = ptr ;
0053     _namemap[ptr] = name ;
0054     _argnamemap[ptr].push_back(arg1name) ;
0055     _argnamemap[ptr].push_back(arg2name) ;
0056     _argnamemap[ptr].push_back(arg3name) ;
0057     _argnamemap[ptr].push_back(arg4name) ;
0058   }
0059 
0060 
0061   const char* lookupName(VO (*ptr)(VI1,VI2,VI3,VI4)) {
0062     // Return name of function given by pointer
0063     return _namemap[ptr].c_str() ;
0064   }
0065 
0066   VO (*lookupPtr(const char* name))(VI1,VI2,VI3,VI4) {
0067     // Return pointer of function given by name
0068     return _ptrmap[name] ;
0069   }
0070 
0071   const char* lookupArgName(VO (*ptr)(VI1,VI2,VI3,VI4), UInt_t iarg) {
0072     // Return name of i-th argument of function. If function is
0073     // not registered, argument names 0,1,2 are x,y,z
0074     if (iarg<_argnamemap[ptr].size()) {
0075       return (_argnamemap[ptr])[iarg].c_str() ;
0076     }
0077     switch (iarg) {
0078     case 0: return "x" ;
0079     case 1: return "y" ;
0080     case 2: return "z" ;
0081     case 3: return "w" ;
0082     }
0083     return "v" ;
0084   }
0085 
0086  private:
0087 
0088   std::map<std::string,VO (*)(VI1,VI2,VI3,VI4)> _ptrmap ; // Pointer-to-name map
0089   std::map<VO (*)(VI1,VI2,VI3,VI4),std::string> _namemap ; // Name-to-pointer map
0090   std::map<VO (*)(VI1,VI2,VI3,VI4),std::vector<std::string> > _argnamemap ; // Pointer-to-argnamelist map
0091 } ;
0092 
0093 
0094 
0095 template<class VO, class VI1, class VI2, class VI3, class VI4>
0096 class RooCFunction4Ref : public TObject {
0097  public:
0098   RooCFunction4Ref(VO (*ptr)(VI1,VI2,VI3,VI4)=nullptr) : _ptr(ptr) {
0099     // Constructor of persistable function reference
0100   } ;
0101 
0102   VO operator()(VI1 x,VI2 y,VI3 z,VI4 w) const {
0103     // Evaluate embedded function
0104     return (*_ptr)(x,y,z,w) ;
0105   }
0106 
0107   const char* name() const {
0108     // Return registered name of embedded function. If function
0109     // is not registered return string with hex presentation
0110     // of function pointer value
0111     const char* result = fmap().lookupName(_ptr) ;
0112     if (result && strlen(result)) {
0113       return result ;
0114     }
0115     // This union is to avoid a warning message:
0116     union {
0117        void *_ptr;
0118        func_t _funcptr;
0119     } temp;
0120     temp._funcptr = _ptr;
0121     return Form("(%p)",temp._ptr) ;
0122   }
0123 
0124   const char* argName(Int_t iarg) {
0125     // Return suggested name for i-th argument
0126     return fmap().lookupArgName(_ptr,iarg) ;
0127   }
0128 
0129   static RooCFunction4Map<VO,VI1,VI2,VI3,VI4>& fmap() {
0130     // Return reference to function pointer-to-name mapping service
0131     if (!_fmap) {
0132       _fmap = new RooCFunction4Map<VO,VI1,VI2,VI3,VI4> ;
0133     }
0134     return *_fmap ;
0135   }
0136  private:
0137 
0138   static VO dummyFunction(VI1,VI2,VI3,VI4) {
0139     // Dummy function used when registered function was not
0140     // found in un-persisting object
0141     return 0 ;
0142   }
0143 
0144 
0145   typedef VO (*func_t)(VI1,VI2,VI3,VI4);
0146   func_t _ptr; //! Pointer to embedded function
0147 
0148   static RooCFunction4Map<VO,VI1,VI2,VI3,VI4>* _fmap ; // Pointer to mapping service object
0149 
0150   ClassDefOverride(RooCFunction4Ref,1) // Persistable reference to C function pointer
0151 } ;
0152 
0153 // Define static member
0154 template<class VO, class VI1, class VI2, class VI3, class VI4>
0155 RooCFunction4Map<VO,VI1,VI2,VI3,VI4>* RooCFunction4Ref<VO,VI1,VI2,VI3,VI4>::_fmap = nullptr;
0156 
0157 template<class VO, class VI1, class VI2, class VI3, class VI4>
0158 void RooCFunction4Ref<VO,VI1,VI2,VI3,VI4>::Streamer(TBuffer &R__b)
0159 {
0160   // Custom streamer for function pointer reference object. When writing,
0161   // the function pointer is substituted by its registered name. When function
0162   // is unregistered name 'UNKNOWN' is written and a warning is issues. When
0163   // reading back, the embedded name is converted back to a function pointer
0164   // using the mapping service. When name UNKNOWN is encountered a warning is
0165   // issues and a dummy null function is substituted. When the registered function
0166   // name can not be mapped to a function pointer an ERROR is issued and a pointer
0167   // to the dummy null function is substituted
0168 
0169   typedef ::RooCFunction4Ref<VO,VI1,VI2,VI3,VI4> thisClass;
0170 
0171    // Stream an object of class RooCFunction4Ref
0172    if (R__b.IsReading()) {
0173 
0174      UInt_t R__s;
0175      UInt_t R__c;
0176      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
0177 
0178      // Read name from file
0179      TString tmpName ;
0180      tmpName.Streamer(R__b) ;
0181 
0182      if (tmpName=="UNKNOWN" && R__v>0) {
0183 
0184        coutW(ObjectHandling) << "WARNING: Objected embeds function pointer to unknown function, object will not be functional" << std::endl ;
0185        _ptr = dummyFunction ;
0186 
0187      } else {
0188 
0189        // Lookup pointer to C function with given name
0190        _ptr = fmap().lookupPtr(tmpName.Data()) ;
0191 
0192        if (_ptr==nullptr) {
0193     coutW(ObjectHandling) << "ERROR: Objected embeds pointer to function named " << tmpName
0194                 << " but no such function is registered, object will not be functional" << std::endl ;
0195        }
0196      }
0197 
0198 
0199      R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
0200 
0201    } else {
0202 
0203      UInt_t R__c;
0204      R__c = R__b.WriteVersion(thisClass::IsA(), true);
0205 
0206      // Lookup name of reference C function
0207      TString tmpName = fmap().lookupName(_ptr) ;
0208      if (tmpName.Length()==0) {
0209        coutW(ObjectHandling) << "WARNING: Cannot persist unknown function pointer " << Form("0x%zx",(size_t)_ptr)
0210               << " written object will not be functional when read back" <<  std::endl ;
0211        tmpName="UNKNOWN" ;
0212      }
0213 
0214      // Persist the name
0215      tmpName.Streamer(R__b) ;
0216 
0217      R__b.SetByteCount(R__c, true);
0218 
0219    }
0220 }
0221 
0222 
0223 
0224 template<class VO,class VI1, class VI2, class VI3, class VI4>
0225 class RooCFunction4Binding : public RooAbsReal {
0226 public:
0227   RooCFunction4Binding() {
0228     // Default constructor
0229   } ;
0230   RooCFunction4Binding(const char *name, const char *title, VO (*_func)(VI1,VI2,VI3,VI4), RooAbsReal& _x, RooAbsReal& _y, RooAbsReal& _z, RooAbsReal& _w);
0231   RooCFunction4Binding(const RooCFunction4Binding& other, const char* name=nullptr) ;
0232   TObject* clone(const char* newname) const override { return new RooCFunction4Binding(*this,newname); }
0233 
0234   void printArgs(std::ostream& os) const override {
0235     // Print object arguments and name/address of function pointer
0236     os << "[ function=" << func.name() << " " ;
0237     for (Int_t i=0 ; i<numProxies() ; i++) {
0238       RooAbsProxy* p = getProxy(i) ;
0239       if (!TString(p->name()).BeginsWith("!")) {
0240    p->print(os) ;
0241    os << " " ;
0242       }
0243     }
0244     os << "]" ;
0245   }
0246 
0247 protected:
0248 
0249   RooCFunction4Ref<VO,VI1,VI2,VI3,VI4> func ; // Function pointer reference
0250   RooRealProxy x ;              // Argument reference
0251   RooRealProxy y ;              // Argument reference
0252   RooRealProxy z ;              // Argument reference
0253   RooRealProxy w ;              // Argument reference
0254 
0255   double evaluate() const override {
0256     // Return value of embedded function using value of referenced variable x
0257     return func(x,y,z,w) ;
0258   }
0259 
0260 private:
0261 
0262   ClassDefOverride(RooCFunction4Binding,1) // RooAbsReal binding to external C functions
0263 };
0264 
0265 
0266 template<class VO,class VI1, class VI2, class VI3, class VI4>
0267 RooCFunction4Binding<VO,VI1,VI2,VI3,VI4>::RooCFunction4Binding(const char *name, const char *title, VO (*_func)(VI1,VI2,VI3,VI4),
0268                          RooAbsReal& _x, RooAbsReal& _y, RooAbsReal& _z, RooAbsReal& _w) :
0269   RooAbsReal(name,title),
0270   func(_func),
0271   x(func.argName(0),func.argName(0),this,_x),
0272   y(func.argName(1),func.argName(1),this,_y),
0273   z(func.argName(2),func.argName(2),this,_z),
0274   w(func.argName(3),func.argName(3),this,_w)
0275 {
0276   // Constructor of C function binding object given a pointer to a function and a RooRealVar to which the function
0277   // argument should be bound. This object is fully functional as a RooFit function object. The only restriction is
0278   // if the referenced function is _not_ a standard ROOT TMath or MathCore function it can not be persisted in a
0279   // a RooWorkspace
0280 }
0281 
0282 
0283 template<class VO,class VI1, class VI2, class VI3, class VI4>
0284 RooCFunction4Binding<VO,VI1,VI2,VI3,VI4>::RooCFunction4Binding(const RooCFunction4Binding& other, const char* name) :
0285   RooAbsReal(other,name),
0286   func(other.func),
0287   x("x",this,other.x),
0288   y("y",this,other.y),
0289   z("z",this,other.z),
0290   w("w",this,other.w)
0291 {
0292   // Copy constructor
0293 }
0294 
0295 
0296 template<class VO,class VI1, class VI2, class VI3, class VI4>
0297 class RooCFunction4PdfBinding : public RooAbsPdf {
0298 public:
0299   RooCFunction4PdfBinding() {
0300     // Default constructor
0301   } ;
0302   RooCFunction4PdfBinding(const char *name, const char *title, VO (*_func)(VI1,VI2,VI3,VI4), RooAbsReal& _x, RooAbsReal& _y, RooAbsReal& _z, RooAbsReal& _w);
0303   RooCFunction4PdfBinding(const RooCFunction4PdfBinding& other, const char* name=nullptr) ;
0304   TObject* clone(const char* newname) const override { return new RooCFunction4PdfBinding(*this,newname); }
0305 
0306   void printArgs(std::ostream& os) const override {
0307     // Print object arguments and name/address of function pointer
0308     os << "[ function=" << func.name() << " " ;
0309     for (Int_t i=0 ; i<numProxies() ; i++) {
0310       RooAbsProxy* p = getProxy(i) ;
0311       if (!TString(p->name()).BeginsWith("!")) {
0312    p->print(os) ;
0313    os << " " ;
0314       }
0315     }
0316     os << "]" ;
0317   }
0318 
0319 protected:
0320 
0321   RooCFunction4Ref<VO,VI1,VI2,VI3,VI4> func ; // Function pointer reference
0322   RooRealProxy x ;              // Argument reference
0323   RooRealProxy y ;              // Argument reference
0324   RooRealProxy z ;              // Argument reference
0325   RooRealProxy w ;              // Argument reference
0326 
0327   double evaluate() const override {
0328     // Return value of embedded function using value of referenced variable x
0329     return func(x,y,z,w) ;
0330   }
0331 
0332 private:
0333 
0334   ClassDefOverride(RooCFunction4PdfBinding,1) // RooAbsReal binding to external C functions
0335 };
0336 
0337 
0338 template<class VO,class VI1, class VI2, class VI3, class VI4>
0339 RooCFunction4PdfBinding<VO,VI1,VI2,VI3,VI4>::RooCFunction4PdfBinding(const char *name, const char *title, VO (*_func)(VI1,VI2,VI3,VI4),
0340                          RooAbsReal& _x, RooAbsReal& _y, RooAbsReal& _z, RooAbsReal& _w) :
0341   RooAbsPdf(name,title),
0342   func(_func),
0343   x(func.argName(0),func.argName(0),this,_x),
0344   y(func.argName(1),func.argName(1),this,_y),
0345   z(func.argName(2),func.argName(2),this,_z),
0346   w(func.argName(3),func.argName(3),this,_w)
0347 {
0348   // Constructor of C function binding object given a pointer to a function and a RooRealVar to which the function
0349   // argument should be bound. This object is fully functional as a RooFit function object. The only restriction is
0350   // if the referenced function is _not_ a standard ROOT TMath or MathCore function it can not be persisted in a
0351   // a RooWorkspace
0352 }
0353 
0354 
0355 template<class VO,class VI1, class VI2, class VI3, class VI4>
0356 RooCFunction4PdfBinding<VO,VI1,VI2,VI3,VI4>::RooCFunction4PdfBinding(const RooCFunction4PdfBinding& other, const char* name) :
0357   RooAbsPdf(other,name),
0358   func(other.func),
0359   x("x",this,other.x),
0360   y("y",this,other.y),
0361   z("z",this,other.z),
0362   w("w",this,other.w)
0363 {
0364   // Copy constructor
0365 }
0366 
0367 #endif