Back to home page

EIC code displayed by LXR

 
 

    


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