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