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