00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "RooFit.h"
00029
00030 #include "RooFactoryWSTool.h"
00031 #include "RooAbsReal.h"
00032 #include "RooAbsCategory.h"
00033 #include "RooArgList.h"
00034 #include "RooRealVar.h"
00035 #include "RooCategory.h"
00036 #include "RooMsgService.h"
00037 #include "RooWorkspace.h"
00038 #include "TInterpreter.h"
00039 #include "TClass.h"
00040 #include "TClassTable.h"
00041 #include "RooAbsPdf.h"
00042 #include "RooGaussian.h"
00043 #include <fstream>
00044 #include <vector>
00045 #include <string>
00046 #include "RooGlobalFunc.h"
00047 #include "RooDataSet.h"
00048 #include "RooDataHist.h"
00049 #include "RooCintUtils.h"
00050 #include "RooAddPdf.h"
00051 #include "RooProdPdf.h"
00052 #include "RooSimultaneous.h"
00053 #include "RooFFTConvPdf.h"
00054 #include "RooNumConvPdf.h"
00055 #include "RooResolutionModel.h"
00056 #include "RooProduct.h"
00057 #include "RooAddition.h"
00058 #include "RooChi2Var.h"
00059 #include "RooNLLVar.h"
00060 #include "RooRealSumPdf.h"
00061 #include "RooConstVar.h"
00062 #include "RooDerivative.h"
00063 #include "TROOT.h"
00064
00065 using namespace RooFit ;
00066 using namespace std ;
00067
00068 ClassImp(RooFactoryWSTool)
00069 ;
00070
00071 RooFactoryWSTool* RooFactoryWSTool::_of = 0 ;
00072 map<string,RooFactoryWSTool::IFace*>* RooFactoryWSTool::_hooks=0 ;
00073
00074 static Int_t init()
00075 {
00076 RooFactoryWSTool::IFace* iface = new RooFactoryWSTool::SpecialsIFace ;
00077
00078
00079 RooFactoryWSTool::registerSpecial("SUM",iface) ;
00080 RooFactoryWSTool::registerSpecial("RSUM",iface) ;
00081 RooFactoryWSTool::registerSpecial("ASUM",iface) ;
00082 RooFactoryWSTool::registerSpecial("PROD",iface) ;
00083 RooFactoryWSTool::registerSpecial("SIMUL",iface) ;
00084 RooFactoryWSTool::registerSpecial("EXPR",iface) ;
00085 RooFactoryWSTool::registerSpecial("FCONV",iface) ;
00086 RooFactoryWSTool::registerSpecial("NCONV",iface) ;
00087
00088
00089 RooFactoryWSTool::registerSpecial("sum",iface) ;
00090 RooFactoryWSTool::registerSpecial("prod",iface) ;
00091 RooFactoryWSTool::registerSpecial("expr",iface) ;
00092 RooFactoryWSTool::registerSpecial("nconv",iface) ;
00093
00094
00095 RooFactoryWSTool::registerSpecial("nll",iface) ;
00096 RooFactoryWSTool::registerSpecial("chi2",iface) ;
00097 RooFactoryWSTool::registerSpecial("profile",iface) ;
00098
00099
00100 RooFactoryWSTool::registerSpecial("int",iface) ;
00101 RooFactoryWSTool::registerSpecial("deriv",iface) ;
00102 RooFactoryWSTool::registerSpecial("cdf",iface) ;
00103 RooFactoryWSTool::registerSpecial("PROJ",iface) ;
00104
00105
00106 RooFactoryWSTool::registerSpecial("dataobs",iface) ;
00107 RooFactoryWSTool::registerSpecial("set",iface) ;
00108
00109 return 0 ;
00110 }
00111 static Int_t dummy = init() ;
00112
00113
00114 #ifndef _WIN32
00115 #include <strings.h>
00116 #else
00117
00118 static char *strtok_r(char *s1, const char *s2, char **lasts)
00119 {
00120 char *ret;
00121
00122 if (s1 == NULL)
00123 s1 = *lasts;
00124 while(*s1 && strchr(s2, *s1))
00125 ++s1;
00126 if(*s1 == '\0')
00127 return NULL;
00128 ret = s1;
00129 while(*s1 && !strchr(s2, *s1))
00130 ++s1;
00131 if(*s1)
00132 *s1++ = '\0';
00133 *lasts = s1;
00134 return ret;
00135 }
00136
00137 #endif
00138
00139
00140
00141
00142 RooFactoryWSTool::RooFactoryWSTool(RooWorkspace& inws) : _ws(&inws), _errorCount(0)
00143 {
00144
00145 }
00146
00147
00148
00149
00150 RooFactoryWSTool::~RooFactoryWSTool()
00151 {
00152
00153 }
00154
00155
00156
00157
00158
00159 RooRealVar* RooFactoryWSTool::createVariable(const char* name, Double_t xmin, Double_t xmax)
00160 {
00161
00162
00163
00164 if (_ws->var(name)) {
00165 coutE(ObjectHandling) << "RooFactoryWSTool::createFactory() ERROR: variable with name '" << name << "' already exists" << endl ;
00166 logError() ;
00167 return 0 ;
00168 }
00169
00170
00171 RooRealVar var(name,name,xmin,xmax) ;
00172
00173
00174 if (_ws->import(var,Silence())) logError() ;
00175
00176 return _ws->var(name) ;
00177 }
00178
00179
00180
00181
00182 RooCategory* RooFactoryWSTool::createCategory(const char* name, const char* stateNameList)
00183 {
00184
00185
00186
00187
00188
00189
00190 RooCategory cat(name,name) ;
00191
00192
00193 if (stateNameList) {
00194 char *tmp = new char[strlen(stateNameList)+1] ;
00195 strlcpy(tmp,stateNameList,strlen(stateNameList)+1) ;
00196 char* save ;
00197 char* tok = strtok_r(tmp,",",&save) ;
00198 while(tok) {
00199 char* sep = strchr(tok,'=') ;
00200 if (sep) {
00201 *sep = 0 ;
00202 Int_t id = atoi(sep+1) ;
00203 cat.defineType(tok,id) ;
00204 *sep = '=' ;
00205 } else {
00206 cat.defineType(tok) ;
00207 }
00208 tok = strtok_r(0,",",&save) ;
00209 }
00210 delete[] tmp ;
00211 }
00212
00213 cat.setStringAttribute("factory_tag",Form("%s[%s]",name,stateNameList)) ;
00214
00215
00216 if (_ws->import(cat,Silence())) logError() ;
00217
00218 return _ws->cat(name) ;
00219 }
00220
00221
00222
00223
00224 RooAbsArg* RooFactoryWSTool::createArg(const char* className, const char* objName, const char* varList)
00225 {
00226
00227
00228
00229
00230
00231
00232 TClass* tc = resolveClassName(className) ;
00233 if (!tc) {
00234 coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR class " << className << " not found in factory alias table, nor in ROOT class table" << endl ;
00235 logError() ;
00236 return 0 ;
00237 }
00238
00239 className = tc->GetName() ;
00240
00241
00242 if (!tc->InheritsFrom(RooAbsArg::Class())) {
00243 coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR class " << className << " does not inherit from RooAbsArg" << endl ;
00244 logError() ;
00245 return 0 ;
00246 }
00247
00248
00249 _args.clear() ;
00250 char tmp[1024] ;
00251 strlcpy(tmp,varList,1024) ;
00252 char* p=tmp ;
00253 char* tok=tmp ;
00254 Int_t blevel(0) ;
00255 Bool_t litmode(kFALSE) ;
00256 while(*p) {
00257
00258
00259 if (*p=='{' || *p=='(' || *p=='[') blevel++ ;
00260 if (*p=='}' || *p==')' || *p==']') blevel-- ;
00261
00262
00263 if (*p=='"' || *p=='\'') litmode = !litmode ;
00264
00265
00266
00267
00268 if (!litmode && blevel==0 && ((*p)==',')) {
00269 *p = 0 ;
00270 _args.push_back(tok) ;
00271 tok = p+1 ;
00272 }
00273
00274 p++ ;
00275 }
00276 _args.push_back(tok) ;
00277
00278
00279
00280 pair<list<string>,unsigned int> ca = RooCintUtils::ctorArgs(className,_args.size()+2) ;
00281 if (ca.first.size()==0) {
00282 coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR no suitable constructor found for class " << className << endl ;
00283 logError() ;
00284 return 0 ;
00285 }
00286
00287
00288
00289 if (_args.size()+2<ca.second || _args.size()+2>ca.first.size()) {
00290 if (ca.second==ca.first.size()) {
00291 coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR number of arguments provided (" << _args.size() << ") for class is invalid, " << className
00292 << " expects " << ca.first.size()-2 << endl ;
00293 logError() ;
00294 } else {
00295 coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR number of arguments provided (" << _args.size() << ") for class is invalid " << className
00296 << " expect number between " << ca.second-2 << " and " << ca.first.size()-2 << endl ;
00297 logError() ;
00298 }
00299 return 0 ;
00300 }
00301
00302
00303 string cintExpr(Form("new %s(\"%s\",\"%s\"",className,objName,objName)) ;
00304
00305
00306 _of = this ;
00307
00308
00309 try {
00310 Int_t i(0) ;
00311 list<string>::iterator ti = ca.first.begin() ; ti++ ; ti++ ;
00312 for (vector<string>::iterator ai = _args.begin() ; ai != _args.end() ; ai++,ti++,i++) {
00313 if ((*ti)=="RooAbsReal&" || (*ti)=="const RooAbsReal&") {
00314 RooFactoryWSTool::as_FUNC(i) ;
00315 cintExpr += Form(",RooFactoryWSTool::as_FUNC(%d)",i) ;
00316 } else if ((*ti)=="RooAbsArg&" || (*ti)=="const RooAbsArg&") {
00317 RooFactoryWSTool::as_ARG(i) ;
00318 cintExpr += Form(",RooFactoryWSTool::as_ARG(%d)",i) ;
00319 } else if ((*ti)=="RooRealVar&" || (*ti)=="const RooRealVar&") {
00320 RooFactoryWSTool::as_VAR(i) ;
00321 cintExpr += Form(",RooFactoryWSTool::as_VAR(%d)",i) ;
00322 } else if ((*ti)=="RooAbsRealLValue&" || (*ti)=="const RooAbsRealLValue&") {
00323 RooFactoryWSTool::as_VARLV(i) ;
00324 cintExpr += Form(",RooFactoryWSTool::as_VARLV(%d)",i) ;
00325 } else if ((*ti)=="RooCategory&" || (*ti)=="const RooCategory&") {
00326 RooFactoryWSTool::as_CAT(i) ;
00327 cintExpr += Form(",RooFactoryWSTool::as_CAT(%d)",i) ;
00328 } else if ((*ti)=="RooAbsCategory&" || (*ti)=="const RooAbsCategory&") {
00329 RooFactoryWSTool::as_CATFUNC(i) ;
00330 cintExpr += Form(",RooFactoryWSTool::as_CATFUNC(%d)",i) ;
00331 } else if ((*ti)=="RooAbsCategoryLValue&" || (*ti)=="const RooAbsCategoryLValue&") {
00332 RooFactoryWSTool::as_CATLV(i) ;
00333 cintExpr += Form(",RooFactoryWSTool::as_CATLV(%d)",i) ;
00334 } else if ((*ti)=="RooAbsPdf&" || (*ti)=="const RooAbsPdf&") {
00335 RooFactoryWSTool::as_PDF(i) ;
00336 cintExpr += Form(",RooFactoryWSTool::as_PDF(%d)",i) ;
00337 } else if ((*ti)=="RooResolutionModel&" || (*ti)=="const RooResolutionModel&") {
00338 RooFactoryWSTool::as_RMODEL(i) ;
00339 cintExpr += Form(",RooFactoryWSTool::as_RMODEL(%d)",i) ;
00340 } else if ((*ti)=="RooAbsData&" || (*ti)=="const RooAbsData&") {
00341 RooFactoryWSTool::as_DATA(i) ;
00342 cintExpr += Form(",RooFactoryWSTool::as_DATA(%d)",i) ;
00343 } else if ((*ti)=="RooDataSet&" || (*ti)=="const RooDataSet&") {
00344 RooFactoryWSTool::as_DSET(i) ;
00345 cintExpr += Form(",RooFactoryWSTool::as_DSET(%d)",i) ;
00346 } else if ((*ti)=="RooDataHist&" || (*ti)=="const RooDataHist&") {
00347 RooFactoryWSTool::as_DHIST(i) ;
00348 cintExpr += Form(",RooFactoryWSTool::as_DHIST(%d)",i) ;
00349 } else if ((*ti)=="const RooArgSet&") {
00350 RooFactoryWSTool::as_SET(i) ;
00351 cintExpr += Form(",RooFactoryWSTool::as_SET(%d)",i) ;
00352 } else if ((*ti)=="const RooArgList&") {
00353 RooFactoryWSTool::as_LIST(i) ;
00354 cintExpr += Form(",RooFactoryWSTool::as_LIST(%d)",i) ;
00355 } else if ((*ti)=="const char*") {
00356 RooFactoryWSTool::as_STRING(i) ;
00357 cintExpr += Form(",RooFactoryWSTool::as_STRING(%d)",i) ;
00358 } else if ((*ti)=="Int_t" || (*ti)=="int" || (*ti)=="Bool_t" || (*ti)=="bool") {
00359 RooFactoryWSTool::as_INT(i) ;
00360 cintExpr += Form(",RooFactoryWSTool::as_INT(%d)",i) ;
00361 } else if ((*ti)=="Double_t") {
00362 RooFactoryWSTool::as_DOUBLE(i) ;
00363 cintExpr += Form(",RooFactoryWSTool::as_DOUBLE(%d)",i) ;
00364 } else if (RooCintUtils::isEnum(ti->c_str())) {
00365 string qualvalue ;
00366 if (_args[i].find(Form("%s::",className)) != string::npos) {
00367 qualvalue = _args[i].c_str() ;
00368 } else {
00369 qualvalue = Form("%s::%s",className,_args[i].c_str()) ;
00370 }
00371 if (RooCintUtils::isValidEnumValue(ti->c_str(),qualvalue.c_str())) {
00372 cintExpr += Form(",(%s)%s",ti->c_str(),qualvalue.c_str()) ;
00373 } else {
00374 throw string(Form("Supplied argument %s does not represent a valid state of enum %s",_args[i].c_str(),ti->c_str())) ;
00375 }
00376 } else {
00377
00378 TObject& obj = RooFactoryWSTool::as_OBJ(i) ;
00379
00380
00381 string btype ;
00382 if (ti->find("const ")==0) {
00383 btype = ti->c_str()+6 ;
00384 } else {
00385 btype = *ti ;
00386 }
00387 if (btype.find("&")) {
00388 btype.erase(btype.size()-1,btype.size()) ;
00389 }
00390
00391
00392 btype = RooCintUtils::trueName(btype.c_str()) ;
00393
00394 if (obj.InheritsFrom(btype.c_str())) {
00395 cintExpr += Form(",(%s&)RooFactoryWSTool::as_OBJ(%d)",ti->c_str(),i) ;
00396 } else {
00397 throw string(Form("Required argument with name %s of type '%s' is not in the workspace",_args[i].c_str(),ti->c_str())) ;
00398 }
00399 }
00400 }
00401 cintExpr += ") ;" ;
00402 } catch (string err) {
00403 coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR constructing " << className << "::" << objName << ": " << err << endl ;
00404 logError() ;
00405 return 0 ;
00406 }
00407
00408 cxcoutD(ObjectHandling) << "RooFactoryWSTool::createArg() Construct expression is " << cintExpr << endl ;
00409
00410
00411 RooAbsArg* arg = (RooAbsArg*) gROOT->ProcessLineFast(cintExpr.c_str()) ;
00412
00413 if (arg) {
00414 if (string(className)=="RooGenericPdf") {
00415 arg->setStringAttribute("factory_tag",Form("EXPR::%s(%s)",objName,varList)) ;
00416 } else if (string(className)=="RooFormulaVar") {
00417 arg->setStringAttribute("factory_tag",Form("expr::%s(%s)",objName,varList)) ;
00418 } else {
00419 arg->setStringAttribute("factory_tag",Form("%s::%s(%s)",className,objName,varList)) ;
00420 }
00421 if (_ws->import(*arg,Silence())) logError() ;
00422 RooAbsArg* ret = _ws->arg(objName) ;
00423 delete arg ;
00424 return ret ;
00425 } else {
00426 coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR in CINT constructor call to create object" << endl ;
00427 logError() ;
00428 return 0 ;
00429 }
00430 }
00431
00432
00433
00434
00435 vector<string> RooFactoryWSTool::ctorArgs(const char* )
00436 {
00437 return vector<string>() ;
00438 }
00439
00440
00441
00442
00443
00444 RooAddPdf* RooFactoryWSTool::add(const char *objName, const char* specList, Bool_t recursiveCoefs)
00445 {
00446
00447
00448
00449 RooArgList pdfList ;
00450 RooArgList coefList ;
00451 RooArgList pdfList2 ;
00452
00453 try {
00454
00455 char buf[1024] ;
00456 strlcpy(buf,specList,1024) ;
00457 char* save ;
00458 char* tok = strtok_r(buf,",",&save) ;
00459 while(tok) {
00460 char* star=strchr(tok,'*') ;
00461 if (star) {
00462 *star=0 ;
00463 pdfList.add(asPDF(star+1)) ;
00464 coefList.add(asFUNC(tok)) ;
00465 } else {
00466 pdfList2.add(asPDF(tok)) ;
00467 }
00468 tok = strtok_r(0,",",&save) ;
00469 }
00470 pdfList.add(pdfList2) ;
00471
00472 } catch (string err) {
00473 coutE(ObjectHandling) << "RooFactoryWSTool::add(" << objName << ") ERROR creating RooAddPdf: " << err << endl ;
00474 logError() ;
00475 return 0 ;
00476 }
00477
00478 RooAddPdf* pdf = new RooAddPdf(objName,objName,pdfList,coefList,recursiveCoefs) ;
00479 pdf->setStringAttribute("factory_tag",Form("SUM::%s(%s)",objName,specList)) ;
00480 if (_ws->import(*pdf,Silence())) logError() ;
00481 return (RooAddPdf*) _ws->pdf(objName) ;
00482 }
00483
00484
00485
00486 RooRealSumPdf* RooFactoryWSTool::amplAdd(const char *objName, const char* specList)
00487 {
00488
00489
00490
00491 RooArgList amplList ;
00492 RooArgList coefList ;
00493 RooArgList amplList2 ;
00494
00495 try {
00496
00497 char buf[1024] ;
00498 strlcpy(buf,specList,1024) ;
00499 char* save ;
00500 char* tok = strtok_r(buf,",",&save) ;
00501 while(tok) {
00502 char* star=strchr(tok,'*') ;
00503 if (star) {
00504 *star=0 ;
00505 amplList.add(asFUNC(star+1)) ;
00506 coefList.add(asFUNC(tok)) ;
00507 } else {
00508 amplList2.add(asFUNC(tok)) ;
00509 }
00510 tok = strtok_r(0,",",&save) ;
00511 }
00512 amplList.add(amplList2) ;
00513
00514 } catch (string err) {
00515 coutE(ObjectHandling) << "RooFactoryWSTool::add(" << objName << ") ERROR creating RooRealSumPdf: " << err << endl ;
00516 logError() ;
00517 return 0 ;
00518 }
00519
00520 RooRealSumPdf* pdf = new RooRealSumPdf(objName,objName,amplList,coefList) ;
00521 pdf->setStringAttribute("factory_tag",Form("ASUM::%s(%s)",objName,specList)) ;
00522 if (_ws->import(*pdf,Silence())) logError() ;
00523 return (RooRealSumPdf*) _ws->pdf(objName) ;
00524 }
00525
00526
00527
00528 RooProdPdf* RooFactoryWSTool::prod(const char *objName, const char* pdfList)
00529 {
00530 _of = this ;
00531
00532
00533 RooLinkedList cmdList ;
00534 string regPdfList="{" ;
00535 char buf[1024] ;
00536 strlcpy(buf,pdfList,1024) ;
00537 char* save ;
00538 char* tok = strtok_r(buf,",",&save) ;
00539 while(tok) {
00540 char *sep = strchr(tok,'|') ;
00541 if (sep) {
00542
00543 *sep=0 ;
00544 sep++ ;
00545
00546 try {
00547 cmdList.Add(Conditional(asSET(tok),asSET(sep),kTRUE).Clone()) ;
00548 } catch (string err) {
00549 coutE(ObjectHandling) << "RooFactoryWSTool::prod(" << objName << ") ERROR creating RooProdPdf Conditional argument: " << err << endl ;
00550 logError() ;
00551 return 0 ;
00552 }
00553
00554 } else {
00555
00556 if (regPdfList.size()>1) {
00557 regPdfList += "," ;
00558 }
00559 regPdfList += tok ;
00560 }
00561 tok = strtok_r(0,",",&save) ;
00562 }
00563 regPdfList += "}" ;
00564
00565 RooProdPdf* pdf = 0 ;
00566 try {
00567 pdf = new RooProdPdf(objName,objName,asSET(regPdfList.c_str()),cmdList) ;
00568 } catch (string err) {
00569 coutE(ObjectHandling) << "RooFactoryWSTool::prod(" << objName << ") ERROR creating RooProdPdf input set of regular p.d.f.s: " << err << endl ;
00570 logError() ;
00571 pdf = 0 ;
00572 }
00573 cmdList.Delete() ;
00574
00575 if (pdf) {
00576 pdf->setStringAttribute("factory_tag",Form("PROD::%s(%s)",objName,pdfList)) ;
00577 if (_ws->import(*pdf,Silence())) logError() ;
00578 delete pdf ;
00579 return (RooProdPdf*) _ws->pdf(objName) ;
00580 } else {
00581 return 0 ;
00582 }
00583 }
00584
00585
00586
00587
00588 RooSimultaneous* RooFactoryWSTool::simul(const char* objName, const char* indexCat, const char* pdfMap)
00589 {
00590 map<string,RooAbsPdf*> theMap ;
00591
00592 char buf[1024] ;
00593 strlcpy(buf,pdfMap,1024) ;
00594 char* save ;
00595 char* tok = strtok_r(buf,",",&save) ;
00596 while(tok) {
00597 char* eq = strchr(tok,'=') ;
00598 if (!eq) {
00599 coutE(ObjectHandling) << "RooFactoryWSTool::simul(" << objName << ") ERROR creating RooSimultaneous::" << objName
00600 << " expect mapping token of form 'state=pdfName', but found '" << tok << "'" << endl ;
00601 logError() ;
00602 return 0 ;
00603 } else {
00604 *eq = 0 ;
00605
00606 try {
00607 theMap[tok] = &asPDF(eq+1) ;
00608 } catch ( string err ) {
00609 coutE(ObjectHandling) << "RooFactoryWSTool::simul(" << objName << ") ERROR creating RooSimultaneous: " << err << endl ;
00610 logError() ;
00611 }
00612 }
00613 tok = strtok_r(0,",",&save) ;
00614 }
00615
00616
00617
00618 RooSimultaneous* pdf(0) ;
00619 try {
00620 pdf = new RooSimultaneous(objName,objName,theMap,asCATLV(indexCat)) ;
00621 } catch (string err) {
00622 coutE(ObjectHandling) << "RooFactoryWSTool::simul(" << objName << ") ERROR creating RooSimultaneous::" << objName << " " << err << endl ;
00623 logError() ;
00624 }
00625
00626
00627 pdf->setStringAttribute("factory_tag",Form("SIMUL::%s(%s,%s)",objName,indexCat,pdfMap)) ;
00628 if (_ws->import(*pdf,Silence())) logError() ;
00629 return (RooSimultaneous*) _ws->pdf(objName) ;
00630 }
00631
00632
00633
00634
00635
00636 RooAddition* RooFactoryWSTool::addfunc(const char *objName, const char* specList)
00637 {
00638
00639 RooArgList sumlist1 ;
00640 RooArgList sumlist2 ;
00641
00642 try {
00643
00644 char buf[1024] ;
00645 strlcpy(buf,specList,1024) ;
00646 char* save ;
00647 char* tok = strtok_r(buf,",",&save) ;
00648 while(tok) {
00649 char* star=strchr(tok,'*') ;
00650 if (star) {
00651 *star=0 ;
00652 sumlist2.add(asFUNC(star+1)) ;
00653 sumlist1.add(asFUNC(tok)) ;
00654 } else {
00655 sumlist1.add(asFUNC(tok)) ;
00656 }
00657 tok = strtok_r(0,",",&save) ;
00658 }
00659
00660 } catch (string err) {
00661 coutE(ObjectHandling) << "RooFactoryWSTool::addfunc(" << objName << ") ERROR creating RooAddition: " << err << endl ;
00662 logError() ;
00663 return 0 ;
00664 }
00665
00666 if (sumlist2.getSize()>0 && (sumlist1.getSize()!=sumlist2.getSize())) {
00667 coutE(ObjectHandling) << "RooFactoryWSTool::addfunc(" << objName << ") ERROR creating RooAddition: syntax error: either all sum terms must be products or none" << endl ;
00668 logError() ;
00669 return 0 ;
00670 }
00671
00672
00673 RooAddition* sum ;
00674 if (sumlist2.getSize()>0) {
00675 sum = new RooAddition(objName,objName,sumlist1,sumlist2) ;
00676 } else {
00677 sum = new RooAddition(objName,objName,sumlist1) ;
00678 }
00679
00680 sum->setStringAttribute("factory_tag",Form("sum::%s(%s)",objName,specList)) ;
00681 if (_ws->import(*sum,Silence())) logError() ;
00682 delete sum ;
00683 return (RooAddition*) _ws->pdf(objName) ;
00684
00685 }
00686
00687
00688
00689
00690
00691 RooProduct* RooFactoryWSTool::prodfunc(const char *objName, const char* pdfList)
00692 {
00693 return (RooProduct*) createArg("RooProduct",objName,Form("{%s}",pdfList)) ;
00694 }
00695
00696
00697
00698
00699
00700
00701 RooAbsArg* RooFactoryWSTool::process(const char* expr)
00702 {
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 if (checkSyntax(expr)) {
00807 return 0 ;
00808 }
00809
00810
00811 char* buf = new char[strlen(expr)+1] ;
00812
00813
00814 char* buftmp = buf ;
00815 while(*expr) {
00816 if (!isspace(*expr)) {
00817 *buftmp = *expr ;
00818 buftmp++ ;
00819 }
00820 expr++ ;
00821 }
00822 *buftmp=0 ;
00823
00824
00825
00826 clearError() ;
00827 ws().startTransaction() ;
00828
00829
00830 string out ;
00831 try {
00832 out = processExpression(buf) ;
00833 } catch (string error) {
00834 coutE(ObjectHandling) << "RooFactoryWSTool::processExpression() ERROR in parsing: " << error << endl ;
00835 logError() ;
00836 }
00837
00838
00839 if (errorCount()>0) {
00840 coutE(ObjectHandling) << "RooFactoryWSTool::processExpression() ERRORS detected, transaction to workspace aborted, no objects committed" << endl ;
00841 ws().cancelTransaction() ;
00842 } else {
00843 ws().commitTransaction() ;
00844 }
00845
00846
00847
00848 delete[] buf ;
00849
00850 return out.size() ? ws().arg(out.c_str()) : 0 ;
00851 }
00852
00853
00854
00855
00856
00857 std::string RooFactoryWSTool::processExpression(const char* token)
00858 {
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 if (string(token).find("$Alias(")==0) {
00870 processAliasExpression(token) ;
00871 }
00872
00873 if (token[0]=='{') {
00874
00875 return processListExpression(token) ;
00876 } else {
00877
00878 return processCompositeExpression(token) ;
00879 }
00880 }
00881
00882
00883
00884
00885 std::string RooFactoryWSTool::processCompositeExpression(const char* token)
00886 {
00887
00888
00889
00890
00891
00892
00893
00894
00895 char* buf_base = new char[strlen(token)+1] ;
00896 char* buf = buf_base ;
00897 strlcpy(buf,token,strlen(token)+1) ;
00898 char* p = buf ;
00899
00900 list<string> singleExpr ;
00901 list<char> separator ;
00902 Int_t blevel(0) ;
00903 Bool_t litmode(kFALSE) ;
00904 while(*p) {
00905
00906
00907 if (*p=='{' || *p=='(' || *p=='[') blevel++ ;
00908 if (*p=='}' || *p==')' || *p==']') blevel-- ;
00909
00910
00911 if (*p=='"' || *p=='\'') litmode = !litmode ;
00912
00913
00914
00915 if (!litmode && blevel==0 && ( (*p)=='=' || (*p) == '|' || (*p) == '*')) {
00916 separator.push_back(*p) ;
00917 *p=0 ;
00918 singleExpr.push_back(buf) ;
00919 buf = p+1 ;
00920 }
00921 p++ ;
00922 }
00923 if (*buf) {
00924 singleExpr.push_back(buf) ;
00925 }
00926 if (singleExpr.size()==1) {
00927 string ret = processSingleExpression(token) ;
00928 delete[] buf_base ;
00929 return ret ;
00930 }
00931
00932 string ret ;
00933 list<char>::iterator ic = separator.begin() ;
00934 for (list<string>::iterator ii = singleExpr.begin() ; ii!=singleExpr.end() ; ii++) {
00935 ret += processSingleExpression(ii->c_str()) ;
00936 if (ic != separator.end()) {
00937 ret += *ic ;
00938 ic++ ;
00939 }
00940 }
00941
00942 delete[] buf_base ;
00943 return ret ;
00944 }
00945
00946
00947
00948
00949 std::string RooFactoryWSTool::processSingleExpression(const char* arg)
00950 {
00951
00952
00953
00954
00955
00956
00957
00958
00959 if (strlen(arg)==0) {
00960 return string("") ;
00961 }
00962
00963
00964 if (arg[0]=='\'' || arg[0]=='"') {
00965 return string(arg) ;
00966 }
00967
00968
00969 char* buf = new char[strlen(arg)+1] ;
00970 strlcpy(buf,arg,strlen(arg)+1) ;
00971 char* bufptr = buf ;
00972
00973 string func,prefix ;
00974 vector<string> args ;
00975
00976
00977 char* save ;
00978 char* tmpx = strtok_r(buf,"([",&save) ;
00979 func = tmpx ? tmpx : "" ;
00980 char* p = strtok_r(0,"",&save) ;
00981
00982
00983 if (!p) {
00984 delete[] buf ;
00985 return arg ;
00986 }
00987
00988
00989 char* tok = p ;
00990 Int_t blevel=0 ;
00991 Bool_t litmode(kFALSE) ;
00992 while(*p) {
00993
00994
00995 if (*p=='{' || *p=='(' || *p=='[') blevel++ ;
00996 if (*p=='}' || *p==')' || *p==']') blevel-- ;
00997
00998
00999 if (*p=='"' || *p=='\'') litmode = !litmode ;
01000
01001
01002
01003
01004
01005 if (!litmode && blevel==0 && ((*p)==',')) {
01006 *p = 0 ;
01007 args.push_back(tok) ;
01008 tok = p+1 ;
01009 }
01010
01011 p++ ;
01012 }
01013
01014
01015
01016 if (p>bufptr && (*(p-1)==')'||*(p-1)==']')) {
01017 *(p-1)=0 ;
01018 }
01019
01020
01021 string tmp = tok ;
01022
01023
01024
01025 p = strtok_r(0,"",&save) ;
01026 if (p) tmp += p ;
01027 args.push_back(tmp) ;
01028
01029
01030 delete[] buf ;
01031
01032
01033
01034 string ret ;
01035
01036
01037 char lb = ' ' ;
01038 for(const char* pp=arg ; *pp!=0 ; pp++) {
01039 if (*pp=='(' || *pp=='[' || *pp=='{') {
01040 lb = *pp ;
01041 break ;
01042 }
01043 }
01044
01045 if (strstr(func.c_str(),"::")) {
01046 if (lb=='(') {
01047
01048 ret= processCreateArg(func,args) ;
01049 } else {
01050 coutE(ObjectHandling) << "RooFactoryWSTool::processSingleExpression(" << arg << "): ERROR: Syntax error: Class::Instance must be followed by (...)" << endl ;
01051 logError() ;
01052 }
01053 } else if (func[0]!='$'){
01054 if (lb=='[') {
01055
01056 ret= processCreateVar(func,args) ;
01057 } else if (lb=='(') {
01058
01059
01060 string autoname ;
01061 if (!_autoNamePrefix.empty()) {
01062
01063
01064 autoname = (Form("%s::%s",func.c_str(),_autoNamePrefix.top().c_str())) ;
01065 } else {
01066
01067 static Int_t globCounter = 0 ;
01068 while(true) {
01069 autoname = Form("gobj%d",globCounter) ;
01070 globCounter++ ;
01071 if (!ws().arg(autoname.c_str())) {
01072 break ;
01073 }
01074 }
01075 autoname = Form("%s::%s",func.c_str(),autoname.c_str()) ;
01076 }
01077 ret= processCreateArg(autoname,args) ;
01078 } else {
01079 coutE(ObjectHandling) << "RooFactoryWSTool::processSingleExpression(" << arg << "): ERROR: Syntax error: expect either Class(...) or Instance[...]" << endl ;
01080 logError() ;
01081 }
01082 } else {
01083 if (lb=='(') {
01084
01085 ret= processMetaArg(func,args) ;
01086 } else {
01087 coutE(ObjectHandling) << "RooFactoryWSTool::processSingleExpression(" << arg << "): ERROR: Syntax error: $MetaClass must be followed by (...)" << endl ;
01088 logError() ;
01089 }
01090 }
01091
01092
01093 return ret ;
01094 }
01095
01096
01097
01098 string RooFactoryWSTool::processListExpression(const char* arg)
01099 {
01100
01101
01102
01103
01104
01105
01106
01107 char* buf = new char[strlen(arg)+1] ;
01108 strlcpy(buf,arg,strlen(arg)+1) ;
01109
01110 vector<string> args ;
01111
01112
01113 char* tok = buf+1 ;
01114 char* p = buf+1 ;
01115
01116
01117 Int_t level(0) ;
01118 while(*p) {
01119
01120
01121 if (*p=='{' || *p=='(' || *p=='[') level++ ;
01122 if (*p=='}' || *p==')' || *p==']') level-- ;
01123
01124
01125
01126
01127
01128 if (level==0 && ((*p)==',')) {
01129 *p = 0 ;
01130 args.push_back(tok) ;
01131 tok = p+1 ;
01132 }
01133
01134 p++ ;
01135 }
01136
01137
01138 if (p>buf && *(p-1)=='}') {
01139 *(p-1)=0 ;
01140 }
01141 args.push_back(tok) ;
01142
01143
01144 delete[] buf ;
01145
01146
01147
01148 string ret("{") ;
01149 vector<string>::iterator iter = args.begin() ;
01150 Int_t i(0) ;
01151 while(iter!= args.end()) {
01152 if (strlen(ret.c_str())>1) ret += "," ;
01153 if (!_autoNamePrefix.empty()) {
01154 _autoNamePrefix.push(Form("%s%d",_autoNamePrefix.top().c_str(),i+1)) ;
01155 }
01156 ret += processSingleExpression(iter->c_str()) ;
01157 if (!_autoNamePrefix.empty()) {
01158 _autoNamePrefix.pop() ;
01159 }
01160 iter++ ;
01161 i++ ;
01162 }
01163 ret += "}" ;
01164
01165 return ret ;
01166 }
01167
01168
01169
01170
01171 string RooFactoryWSTool::processAliasExpression(const char* token)
01172 {
01173
01174 vector<string> args = splitFunctionArgs(token) ;
01175 if (args.size()!=2) {
01176 coutE(ObjectHandling) << "RooFactorWSTool::processAliasExpression() ERROR $Alias() takes exactly two arguments, " << args.size() << " args found" << endl ;
01177 logError() ;
01178 return string() ;
01179 }
01180
01181
01182 _typeAliases[args[1]] = args[0] ;
01183
01184 return string() ;
01185 }
01186
01187
01188
01189
01190
01191 TClass* RooFactoryWSTool::resolveClassName(const char* className)
01192 {
01193
01194
01195 while (true) {
01196 map<string,string>::iterator item = _typeAliases.find(className) ;
01197
01198
01199 if (item != _typeAliases.end()) {
01200 className = item->second.c_str() ;
01201 } else {
01202 break ;
01203 }
01204 }
01205
01206
01207 TClass* tc = TClass::GetClass(className,kTRUE,kTRUE) ;
01208
01209
01210 if (!tc) {
01211 tc = TClass::GetClass(Form("Roo%s",className)) ;
01212 if (!tc) {
01213 coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR class " << className << " not defined in ROOT class table" << endl ;
01214 logError() ;
01215 return 0 ;
01216 }
01217 }
01218 return tc ;
01219 }
01220
01221
01222
01223
01224 string RooFactoryWSTool::varTag(string& func, vector<string>& args)
01225 {
01226 string ret ;
01227 ret += func ;
01228 ret += "[" ;
01229 for (vector<string>::iterator iter = args.begin() ; iter!=args.end() ; ++iter) {
01230 if (iter!=args.begin()) {
01231 ret += "," ;
01232 }
01233 ret += *iter ;
01234 }
01235 ret += "]" ;
01236 return ret ;
01237 }
01238
01239
01240
01241
01242
01243 string RooFactoryWSTool::processCreateVar(string& func, vector<string>& args)
01244 {
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 string first = *(args.begin()) ;
01258 if (isdigit(first[0]) || first[0]=='.' || first[0]=='+' || first[0]=='-') {
01259
01260
01261 vector<string>::iterator ai = args.begin() ;
01262 if (args.size()==1) {
01263
01264
01265 Double_t xinit = atof((ai)->c_str()) ;
01266 cxcoutD(ObjectHandling) << "CREATE variable " << func << " xinit = " << xinit << endl ;
01267 RooRealVar tmp(func.c_str(),func.c_str(),xinit) ;
01268 tmp.setStringAttribute("factory_tag",varTag(func,args).c_str()) ;
01269 if (_ws->import(tmp,Silence())) {
01270 logError() ;
01271 }
01272
01273 } else if (args.size()==2) {
01274
01275
01276 Double_t xlo = atof((ai++)->c_str()) ;
01277 Double_t xhi = atof(ai->c_str()) ;
01278 cxcoutD(ObjectHandling) << "CREATE variable " << func << " xlo = " << xlo << " xhi = " << xhi << endl ;
01279 RooRealVar tmp(func.c_str(),func.c_str(),xlo,xhi) ;
01280 tmp.setStringAttribute("factory_tag",varTag(func,args).c_str()) ;
01281 if (_ws->import(tmp,Silence())) {
01282 logError() ;
01283 }
01284
01285 } else if (args.size()==3) {
01286
01287
01288 Double_t xinit = atof((ai++)->c_str()) ;
01289 Double_t xlo = atof((ai++)->c_str()) ;
01290 Double_t xhi = atof(ai->c_str()) ;
01291 cxcoutD(ObjectHandling) << "CREATE variable " << func << " xinit = " << xinit << " xlo = " << xlo << " xhi = " << xhi << endl ;
01292 RooRealVar tmp(func.c_str(),func.c_str(),xinit,xlo,xhi) ;
01293 tmp.setStringAttribute("factory_tag",varTag(func,args).c_str()) ;
01294 if (_ws->import(tmp,Silence())) {
01295 logError() ;
01296 }
01297 }
01298 } else {
01299
01300
01301 string allStates ;
01302 for (vector<string>::iterator ai = args.begin() ; ai!=args.end() ; ai++) {
01303 if (allStates.size()>0) {
01304 allStates += "," ;
01305 }
01306 allStates += *ai ;
01307 }
01308 createCategory(func.c_str(),allStates.c_str()) ;
01309
01310 }
01311 return func ;
01312 }
01313
01314
01315
01316 string RooFactoryWSTool::processCreateArg(string& func, vector<string>& args)
01317 {
01318
01319
01320
01321
01322
01323
01324
01325
01326 char buf[1024] ;
01327 strlcpy(buf,func.c_str(),1024) ;
01328
01329
01330 char* save ;
01331 const char *className = strtok_r(buf,":",&save) ;
01332 const char *instName = strtok_r(0,":",&save) ;
01333 if (!className) className = "";
01334 if (!instName) instName = "" ;
01335
01336
01337 char pargs[1024] ;
01338 pargs[0] = 0 ;
01339 vector<string>::iterator iter = args.begin() ;
01340 vector<string> pargv ;
01341 Int_t iarg(0) ;
01342 while(iter!=args.end()) {
01343 if (strlen(pargs)>0) strlcat(pargs,",",1024) ;
01344 _autoNamePrefix.push(Form("%s_%d",instName,iarg+1)) ;
01345 string tmp = processExpression(iter->c_str()) ;
01346 _autoNamePrefix.pop() ;
01347 strlcat(pargs,tmp.c_str(),1024) ;
01348 pargv.push_back(tmp) ;
01349 iter++ ;
01350 iarg++ ;
01351 }
01352
01353
01354 for (map<string,IFace*>::iterator ii=hooks().begin() ; ii!=hooks().end() ; ii++) {
01355 }
01356 if (hooks().find(className) != hooks().end()) {
01357 IFace* iface = hooks()[className] ;
01358 return iface->create(*this, className,instName,pargv) ;
01359 }
01360
01361 createArg(className,instName,pargs) ;
01362
01363 return string(instName) ;
01364 }
01365
01366
01367
01368
01369 std::string RooFactoryWSTool::processMetaArg(std::string& func, std::vector<std::string>& args)
01370 {
01371
01372 char pargs[1024] ;
01373 pargs[0] = 0 ;
01374 vector<string>::iterator iter = args.begin() ;
01375 vector<string> pargv ;
01376 while(iter!=args.end()) {
01377 if (strlen(pargs)>0) strlcat(pargs,",",1024) ;
01378 string tmp = processExpression(iter->c_str()) ;
01379 strlcat(pargs,tmp.c_str(),1024) ;
01380 pargv.push_back(tmp) ;
01381 iter++ ;
01382 }
01383
01384 string ret = func+"("+pargs+")" ;
01385 return ret ;
01386 }
01387
01388
01389
01390
01391
01392 vector<string> RooFactoryWSTool::splitFunctionArgs(const char* funcExpr)
01393 {
01394
01395 char* buf = new char[strlen(funcExpr)+1] ;
01396 strlcpy(buf,funcExpr,strlen(funcExpr)+1) ;
01397 char* bufptr = buf ;
01398
01399 string func ;
01400 vector<string> args ;
01401
01402
01403 char* save ;
01404 char* tmpx = strtok_r(buf,"(",&save) ;
01405 func = tmpx ? tmpx : "" ;
01406 char* p = strtok_r(0,"",&save) ;
01407
01408
01409 if (!p) {
01410 delete[] buf ;
01411 return args ;
01412 }
01413
01414 char* tok = p ;
01415 Int_t blevel=0 ;
01416 Bool_t litmode(kFALSE) ;
01417 while(*p) {
01418
01419
01420 if (*p=='{' || *p=='(' || *p=='[') blevel++ ;
01421 if (*p=='}' || *p==')' || *p==']') blevel-- ;
01422
01423
01424 if (*p=='"' || *p=='\'') litmode = !litmode ;
01425
01426
01427
01428
01429
01430 if (!litmode && blevel==0 && ((*p)==',')) {
01431 *p = 0 ;
01432 args.push_back(tok) ;
01433 tok = p+1 ;
01434 }
01435
01436 p++ ;
01437 }
01438
01439
01440
01441 if (p>bufptr && *(p-1)==')') {
01442 *(p-1)=0 ;
01443 }
01444
01445
01446 string tmp = tok ;
01447
01448
01449
01450 p = strtok_r(0,"",&save) ;
01451 if (p) tmp += p ;
01452 args.push_back(tmp) ;
01453
01454
01455 delete[] buf ;
01456
01457 return args ;
01458 }
01459
01460
01461
01462
01463
01464
01465 Bool_t RooFactoryWSTool::checkSyntax(const char* arg)
01466 {
01467
01468
01469
01470
01471 Int_t nParentheses(0), nBracket(0), nAccolade(0) ;
01472 const char* ptr = arg ;
01473 while(*ptr) {
01474 if (*ptr=='(') nParentheses++ ;
01475 if (*ptr==')') nParentheses-- ;
01476 if (*ptr=='[') nBracket++ ;
01477 if (*ptr==']') nBracket-- ;
01478 if (*ptr=='{') nAccolade++ ;
01479 if (*ptr=='}') nAccolade-- ;
01480 ptr++ ;
01481 }
01482 if (nParentheses!=0) {
01483 coutE(ObjectHandling) << "RooFactoryWSTool::checkSyntax ERROR non-matching '" << (nParentheses>0?"(":")") << "' in expression" << endl ;
01484 return kTRUE ;
01485 }
01486 if (nBracket!=0) {
01487 coutE(ObjectHandling) << "RooFactoryWSTool::checkSyntax ERROR non-matching '" << (nBracket>0?"[":"]") << "' in expression" << endl ;
01488 return kTRUE ;
01489 }
01490 if (nAccolade!=0) {
01491 coutE(ObjectHandling) << "RooFactoryWSTool::checkSyntax ERROR non-matching '" << (nAccolade>0?"{":"}") << "' in expression" << endl ;
01492 return kTRUE ;
01493 }
01494 return kFALSE ;
01495 }
01496
01497
01498
01499
01500 void RooFactoryWSTool::checkIndex(UInt_t idx)
01501 {
01502 if (idx>_of->_args.size()-1) {
01503 throw string(Form("Need argument number %d, but only %d args are provided",idx,(Int_t)_of->_args.size())) ;
01504 }
01505 }
01506
01507
01508
01509
01510 RooAbsArg& RooFactoryWSTool::asARG(const char* arg)
01511 {
01512
01513
01514
01515 if (arg[0]=='.' || arg[0]=='+' || arg[0] == '-' || isdigit(arg[0])) {
01516 return RooConst(atof(arg)) ;
01517 }
01518
01519
01520 RooAbsArg* rarg = ws().arg(arg) ;
01521 if (!rarg) {
01522 throw string(Form("RooAbsArg named %s not found",arg)) ;
01523 }
01524 return *rarg ;
01525 }
01526
01527
01528
01529
01530 RooAbsReal& RooFactoryWSTool::asFUNC(const char* arg)
01531 {
01532
01533
01534
01535 if (arg[0]=='.' || arg[0]=='+' || arg[0] == '-' || isdigit(arg[0])) {
01536 return RooConst(atof(arg)) ;
01537 }
01538
01539 RooAbsArg* rarg = ws().arg(arg) ;
01540 if (!rarg) {
01541 throw string(Form("RooAbsReal named %s not found",arg)) ;
01542 }
01543 RooAbsReal* real = dynamic_cast<RooAbsReal*>(rarg) ;
01544 if (!real) {
01545 throw string(Form("Object named %s is not of type RooAbsReal",arg)) ;
01546 }
01547 return *real ;
01548 }
01549
01550
01551
01552
01553 RooAbsRealLValue& RooFactoryWSTool::asVARLV(const char* arg)
01554 {
01555
01556
01557
01558 if (arg[0]=='.' || arg[0]=='+' || arg[0] == '-' || isdigit(arg[0])) {
01559 throw string(Form("Numeric literal provided for argument (%s), but lvalue is required",arg)) ;
01560 }
01561
01562 RooAbsArg* rarg = ws().arg(arg) ;
01563 if (!rarg) {
01564 throw string(Form("RooAbsRealLValue named %s not found",arg)) ;
01565 }
01566 RooAbsRealLValue* reallv = dynamic_cast<RooAbsRealLValue*>(rarg) ;
01567 if (!reallv) {
01568 throw string(Form("Object named %s is not of type RooAbsRealLValue",arg)) ;
01569 }
01570 return *reallv ;
01571 }
01572
01573
01574
01575
01576 RooRealVar& RooFactoryWSTool::asVAR(const char* arg)
01577 {
01578
01579
01580 RooRealVar* var = ws().var(arg) ;
01581 if (!var) {
01582 throw string(Form("RooRealVar named %s not found",arg)) ;
01583 }
01584 return *var ;
01585 }
01586
01587
01588
01589
01590
01591 RooAbsPdf& RooFactoryWSTool::asPDF(const char* arg)
01592 {
01593
01594
01595 RooAbsPdf* pdf = ws().pdf(arg) ;
01596 if (!pdf) {
01597 throw string(Form("RooAbsPdf named %s not found",arg)) ;
01598 }
01599 return *pdf ;
01600 }
01601
01602
01603
01604
01605
01606 RooResolutionModel& RooFactoryWSTool::asRMODEL(const char* arg)
01607 {
01608
01609
01610 RooAbsArg* rarg = ws().arg(arg) ;
01611 if (!rarg) {
01612 throw string(Form("RooResolutionModel named %s not found",arg)) ;
01613 }
01614 RooResolutionModel * rmodel = dynamic_cast<RooResolutionModel*>(rarg) ;
01615 if (!rmodel) {
01616 throw string(Form("Object named %s is not of type RooResolutionModel",arg)) ;
01617 }
01618 return *rmodel ;
01619 }
01620
01621
01622
01623
01624
01625 RooAbsCategory& RooFactoryWSTool::asCATFUNC(const char* arg)
01626 {
01627
01628
01629 RooAbsArg* rarg = ws().arg(arg) ;
01630 if (!rarg) {
01631 throw string(Form("RooAbsCategory named %s not found",arg)) ;
01632 }
01633 RooAbsCategory* catf = dynamic_cast<RooAbsCategory*>(rarg) ;
01634 if (!catf) {
01635 throw string(Form("Object named %s is not of type RooAbsCategory",arg)) ;
01636 }
01637 return *catf ;
01638 }
01639
01640
01641
01642
01643 RooAbsCategoryLValue& RooFactoryWSTool::asCATLV(const char* arg)
01644 {
01645
01646
01647 RooAbsArg* rarg = ws().arg(arg) ;
01648 if (!rarg) {
01649 throw string(Form("RooAbsCategoryLValue named %s not found",arg)) ;
01650 }
01651
01652 RooAbsCategoryLValue* catlv = dynamic_cast<RooAbsCategoryLValue*>(rarg) ;
01653 if (!catlv) {
01654 throw string(Form("Object named %s is not of type RooAbsCategoryLValue",arg)) ;
01655 }
01656 return *catlv ;
01657 }
01658
01659
01660
01661
01662 RooCategory& RooFactoryWSTool::asCAT(const char* arg)
01663 {
01664
01665
01666 RooCategory* cat = ws().cat(arg) ;
01667 if (!cat) {
01668 throw string(Form("RooCategory named %s not found",arg)) ;
01669 }
01670 return *cat ;
01671 }
01672
01673
01674
01675
01676
01677
01678 RooArgSet RooFactoryWSTool::asSET(const char* arg)
01679 {
01680
01681
01682 char tmp[1024] ;
01683 strlcpy(tmp,arg,1024) ;
01684
01685 RooArgSet s ;
01686
01687
01688 if (arg[0]!='{') {
01689 const RooArgSet* defSet = ws().set(arg) ;
01690 if (defSet) {
01691 s.add(*defSet) ;
01692 return s ;
01693 }
01694 }
01695
01696 char* save ;
01697 char* tok = strtok_r(tmp,",{}",&save) ;
01698 while(tok) {
01699
01700
01701 if (tok[0]=='.' || tok[0]=='+' || tok[0] == '-' || isdigit(tok[0])) {
01702 s.add(RooConst(atof(tok))) ;
01703 } else {
01704 RooAbsArg* aarg = ws().arg(tok) ;
01705 if (aarg) {
01706 s.add(*aarg) ;
01707 } else {
01708 throw string(Form("RooAbsArg named %s not found",tok)) ;
01709 }
01710 }
01711 tok = strtok_r(0,",{}",&save) ;
01712 }
01713
01714 return s ;
01715 }
01716
01717
01718
01719
01720 RooArgList RooFactoryWSTool::asLIST(const char* arg)
01721 {
01722
01723
01724 char tmp[1024] ;
01725 strlcpy(tmp,arg,1024) ;
01726
01727 RooArgList l ;
01728 char* save ;
01729 char* tok = strtok_r(tmp,",{}",&save) ;
01730 while(tok) {
01731
01732
01733 if (tok[0]=='.' || tok[0]=='+' || tok[0] == '-' || isdigit(tok[0])) {
01734 l.add(RooConst(atof(tok))) ;
01735 } else {
01736 RooAbsArg* aarg = ws().arg(tok) ;
01737 if (aarg) {
01738 l.add(*aarg) ;
01739 } else {
01740 throw string(Form("RooAbsArg named %s not found",tok)) ;
01741 }
01742 }
01743 tok = strtok_r(0,",{}",&save) ;
01744 }
01745
01746 return l ;
01747 }
01748
01749
01750
01751
01752 RooAbsData& RooFactoryWSTool::asDATA(const char* arg)
01753 {
01754
01755
01756 RooAbsData* data = ws().data(arg) ;
01757 if (!data) {
01758 throw string(Form("RooAbsData named %s not found",arg)) ;
01759 }
01760 return *data ;
01761 }
01762
01763
01764
01765
01766 RooDataHist& RooFactoryWSTool::asDHIST(const char* arg)
01767 {
01768
01769
01770 RooAbsData* data = ws().data(arg) ;
01771 if (!data) {
01772 throw string(Form("RooAbsData named %s not found",arg)) ;
01773 }
01774 RooDataHist* hist = dynamic_cast<RooDataHist*>(data) ;
01775 if (!hist) {
01776 throw string(Form("Dataset named %s is not of type RooDataHist",arg)) ;
01777 }
01778 return *hist ;
01779 }
01780
01781
01782
01783 RooDataSet& RooFactoryWSTool::asDSET(const char* arg)
01784 {
01785
01786
01787 RooAbsData* data = ws().data(arg) ;
01788 if (!data) {
01789 throw string(Form("RooAbsData named %s not found",arg)) ;
01790 }
01791 RooDataSet* dset = dynamic_cast<RooDataSet*>(data) ;
01792 if (!dset) {
01793 throw string(Form("Dataset named %s is not of type RooDataSet",arg)) ;
01794 }
01795 return *dset ;
01796 }
01797
01798
01799
01800
01801 TObject& RooFactoryWSTool::asOBJ(const char* arg)
01802 {
01803 TObject* obj = ws().obj(arg) ;
01804 if (!obj) {
01805 throw string(Form("Object named %s not found",arg)) ;
01806 }
01807 return *obj ;
01808 }
01809
01810
01811
01812
01813 const char* RooFactoryWSTool::asSTRING(const char* arg)
01814 {
01815
01816
01817 static vector<string> cbuf(10) ;
01818 static unsigned int cbuf_idx = 0 ;
01819
01820
01821 if (arg==0 || strlen(arg)==0) {
01822 return 0 ;
01823 }
01824
01825
01826
01827 cbuf[cbuf_idx].clear() ;
01828 const char* p = arg+1 ;
01829 while(*p && (*p) != '"' && (*p) !='\'' ) {
01830 cbuf[cbuf_idx] += *(p++) ;
01831 }
01832 const char* ret = cbuf[cbuf_idx].c_str() ;
01833
01834
01835 cbuf_idx++ ;
01836 if (cbuf_idx==cbuf.size()) cbuf_idx=0 ;
01837
01838 return ret ;
01839 }
01840
01841
01842
01843 Int_t RooFactoryWSTool::asINT(const char* arg)
01844 {
01845
01846
01847 return atoi(arg) ;
01848 }
01849
01850
01851
01852 Double_t RooFactoryWSTool::asDOUBLE(const char* arg)
01853 {
01854
01855
01856 return atof(arg) ;
01857 }
01858
01859
01860
01861 void RooFactoryWSTool::registerSpecial(const char* typeName, RooFactoryWSTool::IFace* iface)
01862 {
01863
01864 hooks()[typeName] = iface ;
01865 }
01866
01867
01868
01869
01870 std::map<std::string,RooFactoryWSTool::IFace*>& RooFactoryWSTool::hooks()
01871 {
01872 if (_hooks) return *_hooks ;
01873 _hooks = new map<string,IFace*> ;
01874 return *_hooks ;
01875 }
01876
01877
01878
01879
01880 std::string RooFactoryWSTool::SpecialsIFace::create(RooFactoryWSTool& ft, const char* typeName, const char* instName, std::vector<std::string> args)
01881 {
01882
01883 char pargs[1024] ;
01884 pargs[0] = 0 ;
01885 vector<string>::iterator iter = args.begin() ;
01886 vector<string> pargv ;
01887 while(iter!=args.end()) {
01888 if (strlen(pargs)>0) strlcat(pargs,",",1024) ;
01889 string tmp = ft.processExpression(iter->c_str()) ;
01890 strlcat(pargs,tmp.c_str(),1024) ;
01891 pargv.push_back(tmp) ;
01892 iter++ ;
01893 }
01894
01895
01896 string cl(typeName) ;
01897 if (cl=="SUM") {
01898
01899
01900 ft.add(instName,pargs,kFALSE) ;
01901
01902 } else if (cl=="RSUM") {
01903
01904
01905 ft.add(instName,pargs,kTRUE) ;
01906
01907 } else if (cl=="ASUM") {
01908
01909
01910 ft.amplAdd(instName,pargs) ;
01911
01912 } else if (cl=="PROD") {
01913
01914
01915 ft.prod(instName,pargs) ;
01916
01917 } else if (cl=="SIMUL") {
01918
01919
01920 if (pargv.size()>1) {
01921 ft.simul(instName,pargv[0].c_str(),strchr(pargs,',')+1) ;
01922 } else {
01923 throw string(Form("Need at least two arguments in call to SIMUL::%s, have %d: %s",instName,(Int_t)pargv.size(),pargs)) ;
01924 }
01925
01926 } else if (cl=="EXPR") {
01927
01928
01929 if (args.size()<=2) {
01930 ft.createArg("RooGenericPdf",instName,pargs) ;
01931 } else {
01932 char genargs[1024] ;
01933 strlcpy(genargs,args[0].c_str(),1024) ;
01934 strlcat(genargs,",{",1024) ;
01935 for (UInt_t i=1 ; i<args.size() ; i++) {
01936 if (i!=1) strlcat(genargs,",",1024) ;
01937 strlcat(genargs,args[i].c_str(),1024) ;
01938 }
01939 strlcat(genargs,"}",1024) ;
01940 ft.createArg("RooGenericPdf",instName,genargs) ;
01941 }
01942
01943 } else if (cl=="FCONV") {
01944
01945
01946 ft.createArg("RooFFTConvPdf",instName,pargs) ;
01947
01948 } else if (cl=="NCONV") {
01949
01950
01951 ft.createArg("RooNumConvPdf",instName,pargs) ;
01952
01953 } else if (cl=="sum") {
01954
01955
01956 ft.addfunc(instName,pargs) ;
01957
01958 } else if (cl=="prod") {
01959
01960
01961 ft.prodfunc(instName,pargs) ;
01962
01963 } else if (cl=="expr") {
01964
01965
01966 if (args.size()<=2) {
01967 ft.createArg("RooFormulaVar",instName,pargs) ;
01968 } else {
01969 char genargs[1024] ;
01970 strlcpy(genargs,args[0].c_str(),1024) ;
01971 strlcat(genargs,",{",1024) ;
01972 for (UInt_t i=1 ; i<args.size() ; i++) {
01973 if (i!=1) strlcat(genargs,",",1024) ;
01974 strlcat(genargs,args[i].c_str(),1024) ;
01975 }
01976 strlcat(genargs,"}",1024) ;
01977 ft.createArg("RooFormulaVar",instName,genargs) ;
01978 }
01979
01980 } else if (cl=="nconv") {
01981
01982
01983 ft.createArg("RooNumConvolution",instName,pargs) ;
01984
01985 } else if (cl=="nll") {
01986
01987
01988 RooNLLVar nll(instName,instName,ft.asPDF(pargv[0].c_str()),ft.asDATA(pargv[1].c_str())) ;
01989 if (ft.ws().import(nll,Silence())) ft.logError() ;
01990
01991 } else if (cl=="chi2") {
01992
01993
01994 RooChi2Var nll(instName,instName,ft.asPDF(pargv[0].c_str()),ft.asDHIST(pargv[1].c_str())) ;
01995 if (ft.ws().import(nll,Silence())) ft.logError() ;
01996
01997 } else if (cl=="profile") {
01998
01999
02000 ft.createArg("RooProfileLL",instName,pargs) ;
02001
02002 } else if (cl=="dataobs") {
02003
02004
02005 RooAbsArg* funcClone = static_cast<RooAbsArg*>(ft.asARG(pargv[1].c_str()).clone(instName)) ;
02006 RooAbsArg* arg = ft.asDSET(pargv[0].c_str()).addColumn(*funcClone) ;
02007 if (!ft.ws().fundArg(arg->GetName())) {
02008 if (ft.ws().import(*arg,Silence())) ft.logError() ;
02009 }
02010 delete funcClone ;
02011
02012 } else if (cl=="int") {
02013
02014
02015
02016
02017
02018
02019 if (pargv.size()<2 || pargv.size()>3) {
02020 throw string(Form("int::%s, requires 2 or 3 arguments, have %d arguments",instName,(Int_t)pargv.size())) ;
02021 }
02022
02023 RooAbsReal& func = ft.asFUNC(pargv[0].c_str()) ;
02024
02025 char buf[256] ;
02026 strlcpy(buf,pargv[1].c_str(),256) ;
02027 char* save ;
02028 const char* intobs = strtok_r(buf,"|",&save) ;
02029 if (!intobs) intobs="" ;
02030
02031 const char* range = strtok_r(0,"",&save) ;
02032 if (!range) range="" ;
02033
02034 RooAbsReal* integral = 0 ;
02035 if (pargv.size()==2) {
02036 if (range && strlen(range)) {
02037 integral = func.createIntegral(ft.asSET(intobs),Range(range)) ;
02038 } else {
02039 integral = func.createIntegral(ft.asSET(intobs)) ;
02040 }
02041 } else {
02042 if (range && strlen(range)) {
02043 integral = func.createIntegral(ft.asSET(intobs),Range(range),NormSet(ft.asSET(pargv[2].c_str()))) ;
02044 } else {
02045 integral = func.createIntegral(ft.asSET(intobs),NormSet(ft.asSET(pargv[2].c_str()))) ;
02046 }
02047 }
02048
02049 integral->SetName(instName) ;
02050 if (ft.ws().import(*integral,Silence())) ft.logError() ;
02051
02052 } else if (cl=="deriv") {
02053
02054
02055
02056 if (pargv.size()<2 || pargv.size()>3) {
02057 throw string(Form("deriv::%s, requires 2 or 3 arguments, have %d arguments",instName,(Int_t)pargv.size())) ;
02058 }
02059
02060 RooAbsReal& func = ft.asFUNC(pargv[0].c_str()) ;
02061
02062 RooAbsReal* derivative(0) ;
02063 if (pargv.size()==2) {
02064 derivative = func.derivative(ft.asVAR(pargv[1].c_str()),1) ;
02065 } else {
02066 derivative = func.derivative(ft.asVAR(pargv[1].c_str()),ft.asINT(pargv[2].c_str())) ;
02067 }
02068
02069 derivative->SetName(instName) ;
02070 if (ft.ws().import(*derivative,Silence())) ft.logError() ;
02071
02072 } else if (cl=="cdf") {
02073
02074
02075
02076 if (pargv.size()<2 || pargv.size()>3) {
02077 throw string(Form("cdf::%s, requires 2 or 3 arguments, have %d arguments",instName,(Int_t)pargv.size())) ;
02078 }
02079
02080 RooAbsPdf& pdf = ft.asPDF(pargv[0].c_str()) ;
02081
02082 RooAbsReal* cdf(0) ;
02083 if (pargv.size()==2) {
02084 cdf = pdf.createCdf(ft.asSET(pargv[1].c_str())) ;
02085 } else {
02086 cdf = pdf.createCdf(ft.asSET(pargv[1].c_str()),ft.asSET(pargv[2].c_str())) ;
02087 }
02088
02089 cdf->SetName(instName) ;
02090 if (ft.ws().import(*cdf,Silence())) ft.logError() ;
02091
02092
02093 } else if (cl=="PROJ") {
02094
02095
02096 if (pargv.size()!=2) {
02097 throw string(Form("PROJ::%s, requires 2 arguments, have %d arguments",instName,(Int_t)pargv.size())) ;
02098 }
02099
02100 RooAbsPdf& pdf = ft.asPDF(pargv[0].c_str()) ;
02101 RooAbsPdf* projection = pdf.createProjection(ft.asSET(pargv[1].c_str())) ;
02102 projection->SetName(instName) ;
02103
02104 if (ft.ws().import(*projection,Silence())) ft.logError() ;
02105
02106 } else if (cl=="set") {
02107
02108
02109 if (ft.ws().defineSet(instName,pargs)) {
02110 ft.logError() ;
02111 return string(instName) ;
02112 }
02113
02114 } else {
02115
02116 throw string(Form("RooFactoryWSTool::SpecialsIFace::create() ERROR: Unknown meta-type %s",typeName)) ;
02117
02118 }
02119 return string(instName) ;
02120 }