00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef ROOCFUNCTION2BINDING
00014 #define ROOCFUNCTION2BINDING
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 namespace RooFit {
00026
00027 typedef Double_t (*CFUNCD2DD)(Double_t,Double_t) ;
00028 typedef Double_t (*CFUNCD2ID)(Int_t,Double_t) ;
00029 typedef Double_t (*CFUNCD2UD)(UInt_t,Double_t) ;
00030 typedef Double_t (*CFUNCD2DI)(Double_t,Int_t) ;
00031 typedef Double_t (*CFUNCD2II)(Int_t,Int_t) ;
00032
00033
00034 RooAbsReal* bindFunction(const char* name,void* func,RooAbsReal& x, RooAbsReal& y) ;
00035 RooAbsPdf* bindPdf(const char* name,void* func,RooAbsReal& x, RooAbsReal& y) ;
00036 #ifndef __CINT__
00037 RooAbsReal* bindFunction(const char* name,CFUNCD2DD func,RooAbsReal& x, RooAbsReal& y) ;
00038 RooAbsReal* bindFunction(const char* name,CFUNCD2ID func,RooAbsReal& x, RooAbsReal& y) ;
00039 RooAbsReal* bindFunction(const char* name,CFUNCD2UD func,RooAbsReal& x, RooAbsReal& y) ;
00040 RooAbsReal* bindFunction(const char* name,CFUNCD2DI func,RooAbsReal& x, RooAbsReal& y) ;
00041 RooAbsReal* bindFunction(const char* name,CFUNCD2II func,RooAbsReal& x, RooAbsReal& y) ;
00042 RooAbsPdf* bindPdf(const char* name,CFUNCD2DD func,RooAbsReal& x, RooAbsReal& y) ;
00043 RooAbsPdf* bindPdf(const char* name,CFUNCD2ID func,RooAbsReal& x, RooAbsReal& y) ;
00044 RooAbsPdf* bindPdf(const char* name,CFUNCD2UD func,RooAbsReal& x, RooAbsReal& y) ;
00045 RooAbsPdf* bindPdf(const char* name,CFUNCD2DI func,RooAbsReal& x, RooAbsReal& y) ;
00046 RooAbsPdf* bindPdf(const char* name,CFUNCD2II func,RooAbsReal& x, RooAbsReal& y) ;
00047 #endif
00048
00049 }
00050
00051 template<class VO, class VI1, class VI2>
00052 class RooCFunction2Map {
00053 public:
00054 RooCFunction2Map() {} ;
00055
00056 void add(const char* name, VO (*ptr)(VI1,VI2), const char* arg1name="x", const char* arg2name="y") {
00057
00058 _ptrmap[name] = ptr ;
00059 _namemap[ptr] = name ;
00060 _argnamemap[ptr].push_back(arg1name) ;
00061 _argnamemap[ptr].push_back(arg2name) ;
00062 }
00063
00064
00065 const char* lookupName(VO (*ptr)(VI1,VI2)) {
00066
00067 return _namemap[ptr].c_str() ;
00068 }
00069
00070 VO (*lookupPtr(const char* name))(VI1,VI2) {
00071
00072 return _ptrmap[name] ;
00073 }
00074
00075 const char* lookupArgName(VO (*ptr)(VI1,VI2), UInt_t iarg) {
00076
00077
00078 if (iarg<_argnamemap[ptr].size()) {
00079 return (_argnamemap[ptr])[iarg].c_str() ;
00080 }
00081 switch (iarg) {
00082 case 0: return "x" ;
00083 case 1: return "y" ;
00084 case 2: return "z" ;
00085 }
00086 return "w" ;
00087 }
00088
00089 private:
00090
00091 #ifndef __CINT__
00092 std::map<std::string,VO (*)(VI1,VI2)> _ptrmap ;
00093 std::map<VO (*)(VI1,VI2),std::string> _namemap ;
00094 std::map<VO (*)(VI1,VI2),std::vector<std::string> > _argnamemap ;
00095 #endif
00096 } ;
00097
00098
00099
00100 template<class VO, class VI1, class VI2>
00101 class RooCFunction2Ref : public TObject {
00102 public:
00103 RooCFunction2Ref(VO (*ptr)(VI1,VI2)=0) : _ptr(ptr) {
00104
00105 } ;
00106 ~RooCFunction2Ref() {} ;
00107
00108 VO operator()(VI1 x,VI2 y) const {
00109
00110 return (*_ptr)(x,y) ;
00111 }
00112
00113 const char* name() const {
00114
00115
00116
00117 const char* result = fmap().lookupName(_ptr) ;
00118 if (result && strlen(result)) {
00119 return result ;
00120 }
00121
00122 union {
00123 void *_ptr;
00124 func_t _funcptr;
00125 } temp;
00126 temp._funcptr = _ptr;
00127 return Form("(%p)",temp._ptr) ;
00128 }
00129
00130 const char* argName(Int_t iarg) {
00131
00132 return fmap().lookupArgName(_ptr,iarg) ;
00133 }
00134
00135 static RooCFunction2Map<VO,VI1,VI2>& fmap() {
00136
00137 if (!_fmap) {
00138 _fmap = new RooCFunction2Map<VO,VI1,VI2> ;
00139 }
00140 return *_fmap ;
00141 }
00142
00143 private:
00144
00145 static VO dummyFunction(VI1,VI2) {
00146
00147
00148 return 0 ;
00149 }
00150
00151 typedef VO (*func_t)(VI1,VI2);
00152 func_t _ptr;
00153
00154 static RooCFunction2Map<VO,VI1,VI2>* _fmap ;
00155
00156 ClassDef(RooCFunction2Ref,1)
00157 } ;
00158
00159
00160
00161 template<class VO, class VI1, class VI2>
00162 void RooCFunction2Ref<VO,VI1,VI2>::Streamer(TBuffer &R__b)
00163 {
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 typedef ::RooCFunction2Ref<VO,VI1,VI2> thisClass;
00174
00175
00176 if (R__b.IsReading()) {
00177
00178 UInt_t R__s, R__c;
00179 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00180
00181
00182 TString tmpName ;
00183 tmpName.Streamer(R__b) ;
00184
00185 if (tmpName=="UNKNOWN" && R__v>0) {
00186
00187 coutW(ObjectHandling) << "WARNING: Objected embeds function pointer to unknown function, object will not be functional" << endl ;
00188 _ptr = dummyFunction ;
00189
00190 } else {
00191
00192
00193 _ptr = fmap().lookupPtr(tmpName.Data()) ;
00194
00195 if (_ptr==0) {
00196 coutW(ObjectHandling) << "ERROR: Objected embeds pointer to function named " << tmpName
00197 << " but no such function is registered, object will not be functional" << endl ;
00198 }
00199 }
00200
00201
00202 R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
00203
00204 } else {
00205
00206 UInt_t R__c;
00207 R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
00208
00209
00210 TString tmpName = fmap().lookupName(_ptr) ;
00211 if (tmpName.Length()==0) {
00212 coutW(ObjectHandling) << "WARNING: Cannot persist unknown function pointer " << Form("0x%lx", (ULong_t)_ptr)
00213 << " written object will not be functional when read back" << endl ;
00214 tmpName="UNKNOWN" ;
00215 }
00216
00217
00218 tmpName.Streamer(R__b) ;
00219
00220 R__b.SetByteCount(R__c, kTRUE);
00221
00222 }
00223 }
00224
00225
00226
00227 template<class VO,class VI1, class VI2>
00228 class RooCFunction2Binding : public RooAbsReal {
00229 public:
00230 RooCFunction2Binding() {
00231
00232 } ;
00233 RooCFunction2Binding(const char *name, const char *title, VO (*_func)(VI1,VI2), RooAbsReal& _x, RooAbsReal& _y);
00234 RooCFunction2Binding(const RooCFunction2Binding& other, const char* name=0) ;
00235 virtual TObject* clone(const char* newname) const { return new RooCFunction2Binding(*this,newname); }
00236 inline virtual ~RooCFunction2Binding() { }
00237
00238 void printArgs(ostream& os) const {
00239
00240 os << "[ function=" << func.name() << " " ;
00241 for (Int_t i=0 ; i<numProxies() ; i++) {
00242 RooAbsProxy* p = getProxy(i) ;
00243 if (!TString(p->name()).BeginsWith("!")) {
00244 p->print(os) ;
00245 os << " " ;
00246 }
00247 }
00248 os << "]" ;
00249 }
00250
00251 protected:
00252
00253 RooCFunction2Ref<VO,VI1,VI2> func ;
00254 RooRealProxy x ;
00255 RooRealProxy y ;
00256
00257 Double_t evaluate() const {
00258
00259 return func(x,y) ;
00260 }
00261
00262 private:
00263
00264 ClassDef(RooCFunction2Binding,1)
00265 };
00266
00267 template<class VO,class VI1, class VI2>
00268 RooCFunction2Binding<VO,VI1,VI2>::RooCFunction2Binding(const char *name, const char *title, VO (*_func)(VI1,VI2),
00269 RooAbsReal& _x, RooAbsReal& _y) :
00270 RooAbsReal(name,title),
00271 func(_func),
00272 x(func.argName(0),func.argName(0),this,_x),
00273 y(func.argName(1),func.argName(1),this,_y)
00274 {
00275
00276
00277
00278
00279 }
00280
00281
00282 template<class VO,class VI1, class VI2>
00283 RooCFunction2Binding<VO,VI1,VI2>::RooCFunction2Binding(const RooCFunction2Binding& other, const char* name) :
00284 RooAbsReal(other,name),
00285 func(other.func),
00286 x("x",this,other.x),
00287 y("y",this,other.y)
00288 {
00289
00290 }
00291
00292
00293
00294
00295 template<class VO,class VI1, class VI2>
00296 class RooCFunction2PdfBinding : public RooAbsPdf {
00297 public:
00298 RooCFunction2PdfBinding() {
00299
00300 } ;
00301 RooCFunction2PdfBinding(const char *name, const char *title, VO (*_func)(VI1,VI2), RooAbsReal& _x, RooAbsReal& _y);
00302 RooCFunction2PdfBinding(const RooCFunction2PdfBinding& other, const char* name=0) ;
00303 virtual TObject* clone(const char* newname) const { return new RooCFunction2PdfBinding(*this,newname); }
00304 inline virtual ~RooCFunction2PdfBinding() { }
00305
00306 void printArgs(ostream& os) const {
00307
00308 os << "[ function=" << func.name() << " " ;
00309 for (Int_t i=0 ; i<numProxies() ; i++) {
00310 RooAbsProxy* p = getProxy(i) ;
00311 if (!TString(p->name()).BeginsWith("!")) {
00312 p->print(os) ;
00313 os << " " ;
00314 }
00315 }
00316 os << "]" ;
00317 }
00318
00319 protected:
00320
00321 RooCFunction2Ref<VO,VI1,VI2> func ;
00322 RooRealProxy x ;
00323 RooRealProxy y ;
00324
00325 Double_t evaluate() const {
00326
00327 return func(x,y) ;
00328 }
00329
00330 private:
00331
00332 ClassDef(RooCFunction2PdfBinding,1)
00333 };
00334
00335 template<class VO,class VI1, class VI2>
00336 RooCFunction2PdfBinding<VO,VI1,VI2>::RooCFunction2PdfBinding(const char *name, const char *title, VO (*_func)(VI1,VI2),
00337 RooAbsReal& _x, RooAbsReal& _y) :
00338 RooAbsPdf(name,title),
00339 func(_func),
00340 x(func.argName(0),func.argName(0),this,_x),
00341 y(func.argName(1),func.argName(1),this,_y)
00342 {
00343
00344
00345
00346
00347 }
00348
00349
00350 template<class VO,class VI1, class VI2>
00351 RooCFunction2PdfBinding<VO,VI1,VI2>::RooCFunction2PdfBinding(const RooCFunction2PdfBinding& other, const char* name) :
00352 RooAbsPdf(other,name),
00353 func(other.func),
00354 x("x",this,other.x),
00355 y("y",this,other.y)
00356 {
00357
00358 }
00359
00360 #endif