File indexing completed on 2025-01-18 10:11:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
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
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
0066 return _namemap[ptr].c_str() ;
0067 }
0068
0069 VO (*lookupPtr(const char* name))(VI1,VI2) {
0070
0071 return _ptrmap[name] ;
0072 }
0073
0074 const char* lookupArgName(VO (*ptr)(VI1,VI2), UInt_t iarg) {
0075
0076
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 ;
0091 std::map<VO (*)(VI1,VI2),std::string> _namemap ;
0092 std::map<VO (*)(VI1,VI2),std::vector<std::string> > _argnamemap ;
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
0102 } ;
0103
0104 VO operator()(VI1 x,VI2 y) const {
0105
0106 return (*_ptr)(x,y) ;
0107 }
0108
0109 const char* name() const {
0110
0111
0112
0113 const char* result = fmap().lookupName(_ptr) ;
0114 if (result && strlen(result)) {
0115 return result ;
0116 }
0117
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
0128 return fmap().lookupArgName(_ptr,iarg) ;
0129 }
0130
0131 static RooCFunction2Map<VO,VI1,VI2>& fmap() {
0132
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
0143
0144 return 0 ;
0145 }
0146
0147 typedef VO (*func_t)(VI1,VI2);
0148 func_t _ptr;
0149
0150 static RooCFunction2Map<VO,VI1,VI2>* _fmap ;
0151
0152 ClassDefOverride(RooCFunction2Ref,1)
0153 } ;
0154
0155
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
0164
0165
0166
0167
0168
0169
0170
0171
0172 typedef ::RooCFunction2Ref<VO,VI1,VI2> thisClass;
0173
0174
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
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
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
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
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
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
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 ;
0253 RooRealProxy x ;
0254 RooRealProxy y ;
0255
0256 double evaluate() const override {
0257
0258 return func(x,y) ;
0259 }
0260
0261 private:
0262
0263 ClassDefOverride(RooCFunction2Binding,1)
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
0275
0276
0277
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
0289 }
0290
0291
0292
0293
0294 template<class VO,class VI1, class VI2>
0295 class RooCFunction2PdfBinding : public RooAbsPdf {
0296 public:
0297 RooCFunction2PdfBinding() {
0298
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
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 ;
0320 RooRealProxy x ;
0321 RooRealProxy y ;
0322
0323 double evaluate() const override {
0324
0325 return func(x,y) ;
0326 }
0327
0328 private:
0329
0330 ClassDefOverride(RooCFunction2PdfBinding,1)
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
0342
0343
0344
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
0356 }
0357
0358 #endif