Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:11:19

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