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