Logo ROOT   6.08/07
Reference Guide
RooFactoryWSTool.cxx
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * @(#)root/roofitcore:$Id$
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2005, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 
17 /**
18 \file RooFactoryWSTool.cxx
19 \class RooFactoryWSTool
20 \ingroup Roofitcore
21 
22 RooFactoryWSTool is a clase like TTree::MakeClass() that generates
23 skeleton code for RooAbsPdf and RooAbsReal functions given
24 a list of input parameter names. The factory can also compile
25 the generated code on the fly, and on request also immediate
26 instantiate objects.
27 **/
28 
29 #include "RooFit.h"
30 
31 #include "RooFactoryWSTool.h"
32 #include "RooAbsReal.h"
33 #include "RooAbsCategory.h"
34 #include "RooArgList.h"
35 #include "RooRealVar.h"
36 #include "RooCategory.h"
37 #include "RooMsgService.h"
38 #include "RooWorkspace.h"
39 #include "TInterpreter.h"
40 #include "TClass.h"
41 #include "TClassTable.h"
42 #include "RooAbsPdf.h"
43 #include "RooGaussian.h"
44 #include <fstream>
45 #include <vector>
46 #include <string>
47 #include "RooGlobalFunc.h"
48 #include "RooDataSet.h"
49 #include "RooDataHist.h"
50 #include "RooCintUtils.h"
51 #include "RooAddPdf.h"
52 #include "RooProdPdf.h"
53 #include "RooSimultaneous.h"
54 #include "RooFFTConvPdf.h"
55 #include "RooNumConvPdf.h"
56 #include "RooResolutionModel.h"
57 #include "RooProduct.h"
58 #include "RooAddition.h"
59 #include "RooChi2Var.h"
60 #include "RooNLLVar.h"
61 #include "RooRealSumPdf.h"
62 #include "RooConstVar.h"
63 #include "RooDerivative.h"
64 #include "TROOT.h"
65 
66 using namespace RooFit ;
67 using namespace std ;
68 
69 #define BUFFER_SIZE 64000
70 
72 ;
73 
75 map<string,RooFactoryWSTool::IFace*>* RooFactoryWSTool::_hooks=0 ;
76 
77 static Int_t init();
78 
79 static Int_t dummy = init() ;
80 
81 static Int_t init()
82 {
84 
85  // Operator p.d.f.s
87  RooFactoryWSTool::registerSpecial("RSUM",iface) ;
88  RooFactoryWSTool::registerSpecial("ASUM",iface) ;
89  RooFactoryWSTool::registerSpecial("PROD",iface) ;
90  RooFactoryWSTool::registerSpecial("SIMUL",iface) ;
91  RooFactoryWSTool::registerSpecial("EXPR",iface) ;
92  RooFactoryWSTool::registerSpecial("FCONV",iface) ;
93  RooFactoryWSTool::registerSpecial("NCONV",iface) ;
94 
95  // Operator functions
97  RooFactoryWSTool::registerSpecial("prod",iface) ;
98  RooFactoryWSTool::registerSpecial("expr",iface) ;
99  RooFactoryWSTool::registerSpecial("nconv",iface) ;
100 
101  // Test statistics
102  RooFactoryWSTool::registerSpecial("nll",iface) ;
103  RooFactoryWSTool::registerSpecial("chi2",iface) ;
104  RooFactoryWSTool::registerSpecial("profile",iface) ;
105 
106  // Integration and derivation
107  RooFactoryWSTool::registerSpecial("int",iface) ;
108  RooFactoryWSTool::registerSpecial("deriv",iface) ;
109  RooFactoryWSTool::registerSpecial("cdf",iface) ;
110  RooFactoryWSTool::registerSpecial("PROJ",iface) ;
111 
112  // Miscellaneous
113  RooFactoryWSTool::registerSpecial("dataobs",iface) ;
114  RooFactoryWSTool::registerSpecial("set",iface) ;
115 
116  (void) dummy;
117  return 0 ;
118 }
119 
120 
121 #ifndef _WIN32
122 #include <strings.h>
123 #else
124 
125 static char *strtok_r(char *s1, const char *s2, char **lasts)
126 {
127  char *ret;
128 
129  if (s1 == NULL)
130  s1 = *lasts;
131  while(*s1 && strchr(s2, *s1))
132  ++s1;
133  if(*s1 == '\0')
134  return NULL;
135  ret = s1;
136  while(*s1 && !strchr(s2, *s1))
137  ++s1;
138  if(*s1)
139  *s1++ = '\0';
140  *lasts = s1;
141  return ret;
142 }
143 
144 #endif
145 
146 
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 
150 RooFactoryWSTool::RooFactoryWSTool(RooWorkspace& inws) : _ws(&inws), _errorCount(0), _autoClassPostFix("")
151 
152 {
153  // Default constructor
154 }
155 
156 
157 
158 ////////////////////////////////////////////////////////////////////////////////
159 /// Destructor
160 
162 {
163 }
164 
165 
166 
167 
168 ////////////////////////////////////////////////////////////////////////////////
169 /// Low-level factory interface for creating a RooRealVar with a given range and initial value
170 
172 {
173  // First check if variable already exists
174  if (_ws->var(name)) {
175  coutE(ObjectHandling) << "RooFactoryWSTool::createFactory() ERROR: variable with name '" << name << "' already exists" << endl ;
176  logError() ;
177  return 0 ;
178  }
179 
180  // Create variable
181  RooRealVar var(name,name,xmin,xmax) ;
182 
183  // Put in workspace
184  if (_ws->import(var,Silence())) logError() ;
185 
186  return _ws->var(name) ;
187 }
188 
189 
190 
191 ////////////////////////////////////////////////////////////////////////////////
192 /// Low-level factory interface for creating a RooCategory with a given list of state names. The State name list
193 /// can be of the form 'name1,name2,name3' or of the form 'name1=id1,name2=id2,name3=id3'
194 
195 RooCategory* RooFactoryWSTool::createCategory(const char* name, const char* stateNameList)
196 {
197  // Create variable
198  RooCategory cat(name,name) ;
199 
200  // Add listed state names
201  if (stateNameList) {
202  const size_t tmpSize = strlen(stateNameList)+1;
203  char *tmp = new char[tmpSize] ;
204  strlcpy(tmp,stateNameList,tmpSize) ;
205  char* save ;
206  char* tok = strtok_r(tmp,",",&save) ;
207  while(tok) {
208  char* sep = strchr(tok,'=') ;
209  if (sep) {
210  *sep = 0 ;
211  Int_t id = atoi(sep+1) ;
212  cat.defineType(tok,id) ;
213  *sep = '=' ;
214  } else {
215  cat.defineType(tok) ;
216  }
217  tok = strtok_r(0,",",&save) ;
218  }
219  delete[] tmp ;
220  }
221 
222  cat.setStringAttribute("factory_tag",Form("%s[%s]",name,stateNameList)) ;
223 
224  // Put in workspace
225  if (_ws->import(cat,Silence())) logError() ;
226 
227  return _ws->cat(name) ;
228 }
229 
230 
231 
232 ////////////////////////////////////////////////////////////////////////////////
233 /// Low-level factory interface for creating a RooAbsPdf of a given class with a given list of input variables
234 /// The variable list varList should be of the form "a,b,c" where the interpretation of the argument is
235 /// dependent on the p.d.f. Set and List arguments can be passed by substituting a single argument with
236 /// the form (a,b,c), i.e. one can set varList to "x,(a0,a1,a2)" to pass a RooAbsReal and a RooArgSet as arguments.
237 
238 RooAbsArg* RooFactoryWSTool::createArg(const char* className, const char* objName, const char* varList)
239 {
240  // Find class in ROOT class table
241  TClass* tc = resolveClassName(className) ;
242  if (!tc) {
243  coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR class " << className << " not found in factory alias table, nor in ROOT class table" << endl ;
244  logError() ;
245  return 0 ;
246  }
247 
248  className = tc->GetName() ;
249 
250  // Check that class inherits from RooAbsPdf
251  if (!tc->InheritsFrom(RooAbsArg::Class())) {
252  coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR class " << className << " does not inherit from RooAbsArg" << endl ;
253  logError() ;
254  return 0 ;
255  }
256 
257 
258  _args.clear() ;
259  char tmp[BUFFER_SIZE] ;
260  strlcpy(tmp,varList,BUFFER_SIZE) ;
261  char* p=tmp ;
262  char* tok=tmp ;
263  Int_t blevel(0) ;
264  Bool_t litmode(kFALSE) ;
265  while(*p) {
266 
267  // Keep track of opening and closing brackets
268  if (*p=='{' || *p=='(' || *p=='[') blevel++ ;
269  if (*p=='}' || *p==')' || *p==']') blevel-- ;
270 
271  // Keep track of string literals
272  if (*p=='"' || *p=='\'') litmode = !litmode ;
273 
274  // If we encounter a comma at zero bracket level
275  // finalize the current token as a completed argument
276  // and start the next token
277  if (!litmode && blevel==0 && ((*p)==',')) {
278  *p = 0 ;
279  _args.push_back(tok) ;
280  tok = p+1 ;
281  }
282 
283  p++ ;
284  }
285  _args.push_back(tok) ;
286 
287 
288  // Try CINT interface
289  pair<list<string>,unsigned int> ca = RooCintUtils::ctorArgs(className,_args.size()+2) ;
290  if (ca.first.size()==0) {
291  coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR no suitable constructor found for class " << className << endl ;
292  logError() ;
293  return 0 ;
294  }
295 
296 
297  // Check if number of provided args is in valid range (add two to accomodate name and title strings)
298  if (_args.size()+2<ca.second || _args.size()+2>ca.first.size()) {
299  if (ca.second==ca.first.size()) {
300  coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR number of arguments provided (" << _args.size() << ") for class is invalid, " << className
301  << " expects " << ca.first.size()-2 << endl ;
302  logError() ;
303  } else {
304  coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR number of arguments provided (" << _args.size() << ") for class is invalid " << className
305  << " expect number between " << ca.second-2 << " and " << ca.first.size()-2 << endl ;
306  logError() ;
307  }
308  return 0 ;
309  }
310 
311  // Now construct CINT constructor spec, start with mandatory name and title args
312  string cintExpr(Form("new %s(\"%s\",\"%s\"",className,objName,objName)) ;
313 
314  // Install argument in static data member to be accessed below through static CINT interface functions
315  _of = this ;
316 
317 
318  try {
319  Int_t i(0) ;
320  list<string>::iterator ti = ca.first.begin() ; ti++ ; ti++ ;
321  for (vector<string>::iterator ai = _args.begin() ; ai != _args.end() ; ai++,ti++,i++) {
322  if ((*ti)=="RooAbsReal&" || (*ti)=="const RooAbsReal&") {
324  cintExpr += Form(",RooFactoryWSTool::as_FUNC(%d)",i) ;
325  } else if ((*ti)=="RooAbsArg&" || (*ti)=="const RooAbsArg&") {
327  cintExpr += Form(",RooFactoryWSTool::as_ARG(%d)",i) ;
328  } else if ((*ti)=="RooRealVar&" || (*ti)=="const RooRealVar&") {
330  cintExpr += Form(",RooFactoryWSTool::as_VAR(%d)",i) ;
331  } else if ((*ti)=="RooAbsRealLValue&" || (*ti)=="const RooAbsRealLValue&") {
333  cintExpr += Form(",RooFactoryWSTool::as_VARLV(%d)",i) ;
334  } else if ((*ti)=="RooCategory&" || (*ti)=="const RooCategory&") {
336  cintExpr += Form(",RooFactoryWSTool::as_CAT(%d)",i) ;
337  } else if ((*ti)=="RooAbsCategory&" || (*ti)=="const RooAbsCategory&") {
339  cintExpr += Form(",RooFactoryWSTool::as_CATFUNC(%d)",i) ;
340  } else if ((*ti)=="RooAbsCategoryLValue&" || (*ti)=="const RooAbsCategoryLValue&") {
342  cintExpr += Form(",RooFactoryWSTool::as_CATLV(%d)",i) ;
343  } else if ((*ti)=="RooAbsPdf&" || (*ti)=="const RooAbsPdf&") {
345  cintExpr += Form(",RooFactoryWSTool::as_PDF(%d)",i) ;
346  } else if ((*ti)=="RooResolutionModel&" || (*ti)=="const RooResolutionModel&") {
348  cintExpr += Form(",RooFactoryWSTool::as_RMODEL(%d)",i) ;
349  } else if ((*ti)=="RooAbsData&" || (*ti)=="const RooAbsData&") {
351  cintExpr += Form(",RooFactoryWSTool::as_DATA(%d)",i) ;
352  } else if ((*ti)=="RooDataSet&" || (*ti)=="const RooDataSet&") {
354  cintExpr += Form(",RooFactoryWSTool::as_DSET(%d)",i) ;
355  } else if ((*ti)=="RooDataHist&" || (*ti)=="const RooDataHist&") {
357  cintExpr += Form(",RooFactoryWSTool::as_DHIST(%d)",i) ;
358  } else if ((*ti)=="const RooArgSet&") {
360  cintExpr += Form(",RooFactoryWSTool::as_SET(%d)",i) ;
361  } else if ((*ti)=="const RooArgList&") {
363  cintExpr += Form(",RooFactoryWSTool::as_LIST(%d)",i) ;
364  } else if ((*ti)=="const char*") {
366  cintExpr += Form(",RooFactoryWSTool::as_STRING(%d)",i) ;
367  } else if ((*ti)=="Int_t" || (*ti)=="int" || (*ti)=="Bool_t" || (*ti)=="bool") {
369  cintExpr += Form(",RooFactoryWSTool::as_INT(%d)",i) ;
370  } else if ((*ti)=="Double_t") {
372  cintExpr += Form(",RooFactoryWSTool::as_DOUBLE(%d)",i) ;
373  } else if (RooCintUtils::isEnum(ti->c_str())) {
374 
375  string qualvalue ;
376  if (_args[i].find(Form("%s::",className)) != string::npos) {
377  qualvalue = _args[i].c_str() ;
378  } else {
379  qualvalue = Form("%s::%s",className,_args[i].c_str()) ;
380  }
381  if (RooCintUtils::isValidEnumValue(ti->c_str(),qualvalue.c_str())) {
382  cintExpr += Form(",(%s)%s",ti->c_str(),qualvalue.c_str()) ;
383  } else {
384  throw string(Form("Supplied argument %s does not represent a valid state of enum %s",_args[i].c_str(),ti->c_str())) ;
385  }
386  } else {
387  // Check if generic object store has argument of given name and type
389 
390  // Strip argument type to bare type (i.e. const X& -> X)
391  string btype ;
392  if (ti->find("const ")==0) {
393  btype = ti->c_str()+6 ;
394  } else {
395  btype = *ti ;
396  }
397  if (btype.find("&")) {
398  btype.erase(btype.size()-1,btype.size()) ;
399  }
400 
401  // If btype if a typedef, substitute it by the true type name
402  btype = RooCintUtils::trueName(btype.c_str()) ;
403 
404  if (obj.InheritsFrom(btype.c_str())) {
405  cintExpr += Form(",(%s&)RooFactoryWSTool::as_OBJ(%d)",ti->c_str(),i) ;
406  } else {
407  throw string(Form("Required argument with name %s of type '%s' is not in the workspace",_args[i].c_str(),ti->c_str())) ;
408  }
409  }
410  }
411  cintExpr += ") ;" ;
412  } catch (string err) {
413  coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR constructing " << className << "::" << objName << ": " << err << endl ;
414  logError() ;
415  return 0 ;
416  }
417 
418  cxcoutD(ObjectHandling) << "RooFactoryWSTool::createArg() Construct expression is " << cintExpr << endl ;
419 
420  // Call CINT to perform constructor call. Catch any error thrown by argument conversion method
421  RooAbsArg* arg = (RooAbsArg*) gROOT->ProcessLineFast(cintExpr.c_str()) ;
422 
423  if (arg) {
424  if (string(className)=="RooGenericPdf") {
425  arg->setStringAttribute("factory_tag",Form("EXPR::%s(%s)",objName,varList)) ;
426  } else if (string(className)=="RooFormulaVar") {
427  arg->setStringAttribute("factory_tag",Form("expr::%s(%s)",objName,varList)) ;
428  } else {
429  arg->setStringAttribute("factory_tag",Form("%s::%s(%s)",className,objName,varList)) ;
430  }
431  if (_ws->import(*arg,Silence())) logError() ;
432  RooAbsArg* ret = _ws->arg(objName) ;
433  delete arg ;
434  return ret ;
435  } else {
436  coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR in CINT constructor call to create object" << endl ;
437  logError() ;
438  return 0 ;
439  }
440 }
441 
442 
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 
446 vector<string> RooFactoryWSTool::ctorArgs(const char* /*className*/)
447 {
448  return vector<string>() ;
449 }
450 
451 
452 
453 
454 ////////////////////////////////////////////////////////////////////////////////
455 
456 RooAddPdf* RooFactoryWSTool::add(const char *objName, const char* specList, Bool_t recursiveCoefs)
457 {
458  // Spec list is of form a*A,b*B,c*C,D [ *d]
459 
460  RooArgList pdfList ;
461  RooArgList coefList ;
462  RooArgList pdfList2 ;
463 
464  try {
465 
466  char buf[BUFFER_SIZE] ;
467  strlcpy(buf,specList,BUFFER_SIZE) ;
468  char* save ;
469  char* tok = strtok_r(buf,",",&save) ;
470  while(tok) {
471  char* star=strchr(tok,'*') ;
472  if (star) {
473  *star=0 ;
474  pdfList.add(asPDF(star+1)) ;
475  coefList.add(asFUNC(tok)) ;
476  } else {
477  pdfList2.add(asPDF(tok)) ;
478  }
479  tok = strtok_r(0,",",&save) ;
480  }
481  pdfList.add(pdfList2) ;
482 
483  } catch (string err) {
484  coutE(ObjectHandling) << "RooFactoryWSTool::add(" << objName << ") ERROR creating RooAddPdf: " << err << endl ;
485  logError() ;
486  return 0 ;
487  }
488 
489  RooAddPdf* pdf = new RooAddPdf(objName,objName,pdfList,coefList,recursiveCoefs) ;
490  pdf->setStringAttribute("factory_tag",Form("SUM::%s(%s)",objName,specList)) ;
491  if (_ws->import(*pdf,Silence())) logError() ;
492  return (RooAddPdf*) _ws->pdf(objName) ;
493 }
494 
495 
496 ////////////////////////////////////////////////////////////////////////////////
497 
498 RooRealSumPdf* RooFactoryWSTool::amplAdd(const char *objName, const char* specList)
499 {
500  // Spec list is of form a*A,b*B,c*C,D [ *d]
501 
502  RooArgList amplList ;
503  RooArgList coefList ;
504  RooArgList amplList2 ;
505 
506  try {
507 
508  char buf[BUFFER_SIZE] ;
509  strlcpy(buf,specList,BUFFER_SIZE) ;
510  char* save ;
511  char* tok = strtok_r(buf,",",&save) ;
512  while(tok) {
513  char* star=strchr(tok,'*') ;
514  if (star) {
515  *star=0 ;
516  amplList.add(asFUNC(star+1)) ;
517  coefList.add(asFUNC(tok)) ;
518  } else {
519  amplList2.add(asFUNC(tok)) ;
520  }
521  tok = strtok_r(0,",",&save) ;
522  }
523  amplList.add(amplList2) ;
524 
525  } catch (string err) {
526  coutE(ObjectHandling) << "RooFactoryWSTool::add(" << objName << ") ERROR creating RooRealSumPdf: " << err << endl ;
527  logError() ;
528  return 0 ;
529  }
530 
531  RooRealSumPdf* pdf = new RooRealSumPdf(objName,objName,amplList,coefList,(amplList.getSize()==coefList.getSize())) ;
532  pdf->setStringAttribute("factory_tag",Form("ASUM::%s(%s)",objName,specList)) ;
533  if (_ws->import(*pdf,Silence())) logError() ;
534  return (RooRealSumPdf*) _ws->pdf(objName) ;
535 }
536 
537 
538 ////////////////////////////////////////////////////////////////////////////////
539 
540 RooProdPdf* RooFactoryWSTool::prod(const char *objName, const char* pdfList)
541 {
542  _of = this ;
543 
544  // Separate conditional and non-conditional p.d.f terms
545  RooLinkedList cmdList ;
546  string regPdfList="{" ;
547  char buf[BUFFER_SIZE] ;
548  strlcpy(buf,pdfList,BUFFER_SIZE) ;
549  char* save ;
550  char* tok = strtok_r(buf,",",&save) ;
551  while(tok) {
552  char *sep = strchr(tok,'|') ;
553  if (sep) {
554  // Conditional term
555  *sep=0 ;
556  sep++ ;
557 
558  // |x is conditional on x, |~x is conditional on all but x
559  Bool_t invCond(kFALSE) ;
560  if (*sep=='~') {
561  invCond=kTRUE ;
562  sep++ ;
563  }
564 
565  try {
566  cmdList.Add(Conditional(asSET(tok),asSET(sep),!invCond).Clone()) ;
567  } catch (string err) {
568  coutE(ObjectHandling) << "RooFactoryWSTool::prod(" << objName << ") ERROR creating RooProdPdf Conditional argument: " << err << endl ;
569  logError() ;
570  return 0 ;
571  }
572 
573  } else {
574  // Regular term
575  if (regPdfList.size()>1) {
576  regPdfList += "," ;
577  }
578  regPdfList += tok ;
579  }
580  tok = strtok_r(0,",",&save) ;
581  }
582  regPdfList += "}" ;
583 
584  RooProdPdf* pdf = 0 ;
585  try {
586  pdf = new RooProdPdf(objName,objName,asSET(regPdfList.c_str()),cmdList) ;
587  } catch (string err) {
588  coutE(ObjectHandling) << "RooFactoryWSTool::prod(" << objName << ") ERROR creating RooProdPdf input set of regular p.d.f.s: " << err << endl ;
589  logError() ;
590  pdf = 0 ;
591  }
592  cmdList.Delete() ;
593 
594  if (pdf) {
595  pdf->setStringAttribute("factory_tag",Form("PROD::%s(%s)",objName,pdfList)) ;
596  if (_ws->import(*pdf,Silence())) logError() ;
597  delete pdf ;
598  return (RooProdPdf*) _ws->pdf(objName) ;
599  } else {
600  return 0 ;
601  }
602 }
603 
604 
605 
606 ////////////////////////////////////////////////////////////////////////////////
607 
608 RooSimultaneous* RooFactoryWSTool::simul(const char* objName, const char* indexCat, const char* pdfMap)
609 {
610  map<string,RooAbsPdf*> theMap ;
611  // Add p.d.f. to index state mappings
612  char buf[BUFFER_SIZE] ;
613  strlcpy(buf,pdfMap,BUFFER_SIZE) ;
614  char* save ;
615  char* tok = strtok_r(buf,",",&save) ;
616  while(tok) {
617  char* eq = strchr(tok,'=') ;
618  if (!eq) {
619  coutE(ObjectHandling) << "RooFactoryWSTool::simul(" << objName << ") ERROR creating RooSimultaneous::" << objName
620  << " expect mapping token of form 'state=pdfName', but found '" << tok << "'" << endl ;
621  logError() ;
622  return 0 ;
623  } else {
624  *eq = 0 ;
625 
626  try {
627  theMap[tok] = &asPDF(eq+1) ;
628  } catch ( string err ) {
629  coutE(ObjectHandling) << "RooFactoryWSTool::simul(" << objName << ") ERROR creating RooSimultaneous: " << err << endl ;
630  logError() ;
631  }
632  }
633  tok = strtok_r(0,",",&save) ;
634  }
635 
636 
637  // Create simultaneous p.d.f.
638  RooSimultaneous* pdf(0) ;
639  try {
640  pdf = new RooSimultaneous(objName,objName,theMap,asCATLV(indexCat)) ;
641  } catch (string err) {
642  coutE(ObjectHandling) << "RooFactoryWSTool::simul(" << objName << ") ERROR creating RooSimultaneous::" << objName << " " << err << endl ;
643  logError() ;
644  }
645 
646  // Import p.d.f into workspace
647  pdf->setStringAttribute("factory_tag",Form("SIMUL::%s(%s,%s)",objName,indexCat,pdfMap)) ;
648  if (_ws->import(*pdf,Silence())) logError() ;
649  return (RooSimultaneous*) _ws->pdf(objName) ;
650 }
651 
652 
653 
654 
655 ////////////////////////////////////////////////////////////////////////////////
656 
657 RooAddition* RooFactoryWSTool::addfunc(const char *objName, const char* specList)
658 {
659  RooArgList sumlist1 ;
660  RooArgList sumlist2 ;
661 
662  try {
663 
664  char buf[BUFFER_SIZE] ;
665  strlcpy(buf,specList,BUFFER_SIZE) ;
666  char* save ;
667  char* tok = strtok_r(buf,",",&save) ;
668  while(tok) {
669  char* star=strchr(tok,'*') ;
670  if (star) {
671  *star=0 ;
672  sumlist2.add(asFUNC(star+1)) ;
673  sumlist1.add(asFUNC(tok)) ;
674  } else {
675  sumlist1.add(asFUNC(tok)) ;
676  }
677  tok = strtok_r(0,",",&save) ;
678  }
679 
680  } catch (string err) {
681  coutE(ObjectHandling) << "RooFactoryWSTool::addfunc(" << objName << ") ERROR creating RooAddition: " << err << endl ;
682  logError() ;
683  return 0 ;
684  }
685 
686  if (sumlist2.getSize()>0 && (sumlist1.getSize()!=sumlist2.getSize())) {
687  coutE(ObjectHandling) << "RooFactoryWSTool::addfunc(" << objName << ") ERROR creating RooAddition: syntax error: either all sum terms must be products or none" << endl ;
688  logError() ;
689  return 0 ;
690  }
691 
692 
693  RooAddition* sum ;
694  if (sumlist2.getSize()>0) {
695  sum = new RooAddition(objName,objName,sumlist1,sumlist2) ;
696  } else {
697  sum = new RooAddition(objName,objName,sumlist1) ;
698  }
699 
700  sum->setStringAttribute("factory_tag",Form("sum::%s(%s)",objName,specList)) ;
701  if (_ws->import(*sum,Silence())) logError() ;
702  delete sum ;
703  return (RooAddition*) _ws->pdf(objName) ;
704 
705 }
706 
707 
708 
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 
712 RooProduct* RooFactoryWSTool::prodfunc(const char *objName, const char* pdfList)
713 {
714  return (RooProduct*) createArg("RooProduct",objName,Form("{%s}",pdfList)) ;
715 }
716 
717 
718 
719 
720 
721 ////////////////////////////////////////////////////////////////////////////////
722 /// Process high-level object creation syntax
723 /// Accepted forms of syntax are
724 ///
725 ///
726 /// Creating variables
727 ///
728 /// x[-10,10] - Create variable x with given range and put it in workspace
729 /// x[3,-10,10] - Create variable x with given range and initial value and put it in workspace
730 /// x[3] - Create variable x with given constant value
731 ///
732 /// <numeric literal> - Numeric literal expressions (0.5, -3 etc..) are converted to a RooConst(<numeric literal>)
733 /// where ever a RooAbsReal or RooAbsArg argument is expected
734 ///
735 /// Creating categories
736 ///
737 /// c[lep,kao,nt1,nt2] - Create category c with given state names
738 /// tag[B0=1,B0bar=-1] - Create category tag with given state names and index assignments
739 ///
740 ///
741 /// Creating functions and p.d.f.s
742 ///
743 /// MyPdf::g(x,m,s) - Create p.d.f or function of type MyPdf with name g with argument x,m,s
744 /// Interpretation and number of arguments are mapped to the constructor arguments of the class
745 /// (after the name and title).
746 ///
747 /// MyPdf(x,m,s) - As above, but with an implicitly defined (unique) object name
748 ///
749 ///
750 /// Creating sets and lists (to be used as inputs above)
751 ///
752 /// {a,b,c} - Create RooArgSet or RooArgList (as determined by context) from given contents
753 ///
754 ///
755 ///
756 /// Objects that are not created, are assumed to exist in the workspace
757 /// Object creation expressions as shown above can be nested, e.g. one can do
758 ///
759 /// RooGaussian::g(x[-10,10],m[0],3)
760 ///
761 /// to create a p.d.f and its variables in one go. This nesting can be applied recursively e.g.
762 ///
763 /// SUM::model( f[0.5,0,1] * RooGaussian::g( x[-10,10], m[0], 3] ),
764 /// RooChebychev::c( x, {a0[0.1],a1[0.2],a2[-0.3]} ))
765 ///
766 /// creates the sum of a Gaussian and a Chebychev and all its variables
767 ///
768 ///
769 /// A seperate series of operator meta-type exists to simplify the construction of composite expressions
770 /// meta-types in all capitals (SUM) create p.d.f.s, meta types in lower case (sum) create
771 /// functions.
772 ///
773 ///
774 /// SUM::name(f1*pdf1,f2*pdf2,pdf3] -- Create sum p.d.f name with value f1*pdf1+f2*pdf2+(1-f1-f2)*pdf3
775 /// RSUM::name(f1*pdf1,f2*pdf2,pdf3] -- Create recursive sum p.d.f. name with value f1*pdf1 + (1-f1)(f2*pdf2 + (1-f2)pdf3)
776 /// ASUM::name(f1*amp1,f2*amp2,amp3] -- Create sum p.d.f. name with value f1*amp1+f2*amp2+(1-f1-f2)*amp3 where amplX are amplitudes of type RooAbsReal
777 /// sum::name(a1,a2,a3] -- Create sum function with value a1+a2+a3
778 /// sum::name(a1*b1,a2*b2,a3*b 3] -- Create sum function with value a1*b1+a2*b2+a3*b3
779 ///
780 /// PROD::name(pdf1,pdf2] -- Create product of p.d.f with 'name' with given input p.d.fs
781 /// PROD::name(pdf1|x,pdf2] -- Create product of conditional p.d.f. pdf1 given x and pdf2
782 /// prod::name(a,b,c] -- Create production function with value a*b*c
783 ///
784 /// SIMUL::name(cat,a=pdf1,b=pdf2] -- Create simultaneous p.d.f index category cat. Make pdf1 to state a, pdf2 to state b
785 ///
786 /// EXPR::name('expr',var,...] -- Create an generic p.d.f that interprets the given expression
787 /// expr::name('expr',var,...] -- Create an generic function that interprets the given expression
788 ///
789 ///
790 /// The functionality of high level object creation tools like RooSimWSTool, RooCustomizer and RooClassFactory
791 /// is also interfaced through meta-types in the factory
792 ///
793 ///
794 /// Interface to RooSimWSTool
795 ///
796 /// SIMCLONE::name( modelPdf, $ParamSplit(...),
797 /// $ParamSplitConstrained(...), $Restrict(...) ] -- Clone-and-customize modelPdf according to ParamSplit and ParamSplitConstrained()
798 /// specifications and return a RooSimultaneous p.d.f. of all built clones
799 ///
800 /// MSIMCLONE::name( masterIndex,
801 /// $AddPdf(mstate1, modelPdf1, $ParamSplit(...)),
802 /// $AddPdf(mstate2,modelPdf2),...) ] -- Clone-and-customize multiple models (modelPdf1,modelPdf2) according to ParamSplit and
803 /// ParamSplitConstrained() specifications and return a RooSimultaneous p.d.f. of all built clones,
804 /// using the specified master index to map prototype p.d.f.s to master states
805 /// Interface to RooCustomizer
806 ///
807 /// EDIT::name( orig, substNode=origNode), ... ] -- Create a clone of input object orig, with the specified replacements operations executed
808 /// EDIT::name( orig, origNode=$REMOVE(), ... ] -- Create clone of input removing term origNode from all PROD() terms that contained it
809 /// EDIT::name( orig, origNode=$REMOVE(prodname,...), ... ] -- As above, but restrict removal of origNode to PROD term(s) prodname,...
810 ///
811 ///
812 /// Interface to RooClassFactory
813 ///
814 /// CEXPR::name('expr',var,...] -- Create an custom compiled p.d.f that evaluates the given expression
815 /// cexpr::name('expr',var,...] -- Create an custom compiled function that evaluates the given expression
816 ///
817 ///
818 /// $MetaType(...) - Meta argument that does not result in construction of an object but is used logically organize
819 /// input arguments in certain operator p.d.f. constructions. The defined meta arguments are context dependent.
820 ///
821 /// The only meta argument that is defined globally is $Alias(typeName,aliasName) to
822 /// define aliases for type names. For the definition of meta arguments in operator p.d.f.s
823 /// see the definitions below
824 
826 {
827 
828 // cout << "RooFactoryWSTool::process() " << expr << endl ;
829 
830  // First perform basic syntax check
831  if (checkSyntax(expr)) {
832  return 0 ;
833  }
834 
835  // Allocate work buffer
836  char* buf = new char[strlen(expr)+1] ;
837 
838  // Copy to buffer while absorbing white space and newlines
839  char* buftmp = buf ;
840  while(*expr) {
841  if (!isspace(*expr)) {
842  *buftmp = *expr ;
843  buftmp++ ;
844  }
845  expr++ ;
846  }
847  *buftmp=0 ;
848 
849 
850  // Clear error count and start a transaction in the workspace
851  clearError() ;
852  ws().startTransaction() ;
853 
854  // Process buffer
855  string out ;
856  try {
857  out = processExpression(buf) ;
858  } catch (string error) {
859  coutE(ObjectHandling) << "RooFactoryWSTool::processExpression() ERROR in parsing: " << error << endl ;
860  logError() ;
861  }
862 
863  // If there were no errors commit the transaction, cancel it otherwise
864  if (errorCount()>0) {
865  coutE(ObjectHandling) << "RooFactoryWSTool::processExpression() ERRORS detected, transaction to workspace aborted, no objects committed" << endl ;
866  ws().cancelTransaction() ;
867  } else {
868  ws().commitTransaction() ;
869  }
870 
871 
872  // Delete buffer
873  delete[] buf ;
874 
875  return out.size() ? ws().arg(out.c_str()) : 0 ;
876 }
877 
878 
879 
880 
881 ////////////////////////////////////////////////////////////////////////////////
882 /// Process a single high-level expression or list of
883 /// expressions. The returned string a the reduced expression where
884 /// all inline object creations have been executed and substituted
885 /// with the name of the created object
886 ///
887 /// e.g. 'RooGaussian::g(x,m,s)' --> 'g'
888 /// '{x(-10,10),s} --> '{x,s}'
889 
890 std::string RooFactoryWSTool::processExpression(const char* token)
891 {
892  // Delegate handling to list processor if token starts with {, otherwise
893  // call single expression processor
894  if (string(token).find("$Alias(")==0) {
895  processAliasExpression(token) ;
896  }
897 
898  if (token[0]=='{') {
899  // Process token as list if it starts with '{'
900  return processListExpression(token) ;
901  } else {
902  // Process token as single item otherwise
903  return processCompositeExpression(token) ;
904  }
905 }
906 
907 
908 
909 ////////////////////////////////////////////////////////////////////////////////
910 /// Process a single composite expression
911 ///
912 /// e.g. 'A=RooGaussian::g[x,m,s]' --> 'A=g'
913 /// e.g. 'f[0,1]*RooGaussian::g[x,m,s]' --> 'f*g'
914 /// e.g. 'RooGaussian::g(x,y,s)|x' --> g|x'
915 /// e.g. '$MetaArg(RooGaussian::g[x,m,s],blah)' --> '$MetaArg(g,blah)'
916 
917 std::string RooFactoryWSTool::processCompositeExpression(const char* token)
918 {
919  // Allocate and fill work buffer
920  const size_t bufBaseSize = strlen(token)+1;
921  char* buf_base = new char[bufBaseSize] ;
922  char* buf = buf_base ;
923  strlcpy(buf,token,bufBaseSize) ;
924  char* p = buf ;
925 
926  list<string> singleExpr ;
927  list<char> separator ;
928  Int_t blevel(0) ;
929  Bool_t litmode(kFALSE) ;
930  while(*p) {
931 
932  // Keep track of opening and closing brackets
933  if (*p=='{' || *p=='(' || *p=='[') blevel++ ;
934  if (*p=='}' || *p==')' || *p==']') blevel-- ;
935 
936  // Keep track of string literals
937  if (*p=='"' || *p=='\'') litmode = !litmode ;
938 
939  // If we are zero-bracket level and encounter a |, store
940  // the remainder of the string as suffix and exit loop
941  if (!litmode && blevel==0 && ( (*p)=='=' || (*p) == '|' || (*p) == '*')) {
942  separator.push_back(*p) ;
943  *p=0 ;
944  singleExpr.push_back(buf) ;
945  buf = p+1 ;
946  }
947  p++ ;
948  }
949  if (*buf) {
950  singleExpr.push_back(buf) ;
951  }
952  if (singleExpr.size()==1) {
953  string ret = processSingleExpression(token) ;
954  delete[] buf_base ;
955  return ret ;
956  }
957 
958  string ret ;
959  list<char>::iterator ic = separator.begin() ;
960  for (list<string>::iterator ii = singleExpr.begin() ; ii!=singleExpr.end() ; ii++) {
961  ret += processSingleExpression(ii->c_str()) ;
962  if (ic != separator.end()) {
963  ret += *ic ;
964  ic++ ;
965  }
966  }
967 
968  delete[] buf_base ;
969  return ret ;
970 }
971 
972 
973 
974 ////////////////////////////////////////////////////////////////////////////////
975 /// Process a single high-level expression. The returned string a the reduced
976 /// expression where all inline object creations have been executed and substituted
977 /// with the name of the created object
978 ///
979 /// e.g. 'RooGaussian::g(x,m,s)' --> 'g'
980 /// e.g. 'x[-10,10]' --> 'x'
981 
982 std::string RooFactoryWSTool::processSingleExpression(const char* arg)
983 {
984  // Handle empty strings here
985  if (strlen(arg)==0) {
986  return string("") ;
987  }
988 
989  // Handle string literal case
990  if (arg[0]=='\'' || arg[0]=='"') {
991  return string(arg) ;
992  }
993 
994  // Allocate and fill work buffer
995  const size_t bufSize = strlen(arg)+1;
996  char* buf = new char[bufSize] ;
997  strlcpy(buf,arg,bufSize) ;
998  char* bufptr = buf ;
999 
1000  string func,prefix ;
1001  vector<string> args ;
1002 
1003  // Process token into arguments
1004  char* save ;
1005  char* tmpx = strtok_r(buf,"([",&save) ;
1006  func = tmpx ? tmpx : "" ;
1007  char* p = strtok_r(0,"",&save) ;
1008 
1009  // Return here if token is fundamental
1010  if (!p) {
1011  delete[] buf ;
1012  return arg ;
1013  }
1014 
1015 
1016  char* tok = p ;
1017  Int_t blevel=0 ;
1018  Bool_t litmode(kFALSE) ;
1019  while(*p) {
1020 
1021  // Keep track of opening and closing brackets
1022  if (*p=='{' || *p=='(' || *p=='[') blevel++ ;
1023  if (*p=='}' || *p==')' || *p==']') blevel-- ;
1024 
1025  // Keep track of string literals
1026  if (*p=='"' || *p=='\'') litmode = !litmode ;
1027 
1028 
1029  // If we encounter a comma at zero bracket level
1030  // finalize the current token as a completed argument
1031  // and start the next token
1032  if (!litmode && blevel==0 && ((*p)==',')) {
1033  *p = 0 ;
1034  args.push_back(tok) ;
1035  tok = p+1 ;
1036  }
1037 
1038  p++ ;
1039  }
1040 
1041  // If the last character was a closing bracket, kill
1042  // it in the buffer
1043  if (p>bufptr && (*(p-1)==')'||*(p-1)==']')) {
1044  *(p-1)=0 ;
1045  }
1046 
1047  // Finalize last token as argument
1048  string tmp = tok ;
1049 
1050  // If there is a suffix left in the work buffer attach it to
1051  // this argument
1052  p = strtok_r(0,"",&save) ;
1053  if (p) tmp += p ;
1054  args.push_back(tmp) ;
1055 
1056  // Delete the work buffer
1057  delete[] buf ;
1058 
1059  // If function contains :: then call createArg to process this arg, otherwise
1060  // call createVariable
1061  string ret ;
1062 
1063  // Determine type of leading bracket
1064  char lb = ' ' ;
1065  for(const char* pp=arg ; *pp!=0 ; pp++) {
1066  if (*pp=='(' || *pp=='[' || *pp=='{') {
1067  lb = *pp ;
1068  break ;
1069  }
1070  }
1071 
1072  if (strstr(func.c_str(),"::")) {
1073  if (lb=='(') {
1074  // Create function argument with instance name
1075  ret= processCreateArg(func,args) ;
1076  } else {
1077  coutE(ObjectHandling) << "RooFactoryWSTool::processSingleExpression(" << arg << "): ERROR: Syntax error: Class::Instance must be followed by (...)" << endl ;
1078  logError() ;
1079  }
1080  } else if (func[0]!='$'){
1081  if (lb=='[') {
1082  // Create variable argument
1083  ret= processCreateVar(func,args) ;
1084  } else if (lb=='(') {
1085 
1086  // Create function argument with autoname
1087  string autoname ;
1088  if (!_autoNamePrefix.empty()) {
1089  // If we're inside a function creation call to a higher level object, use its
1090  // name as base for the autoname
1091  autoname = (Form("%s::%s",func.c_str(),_autoNamePrefix.top().c_str())) ;
1092  } else {
1093  // Otherwise find a free global_%d name
1094  static Int_t globCounter = 0 ;
1095  while(true) {
1096  autoname = Form("gobj%d",globCounter) ;
1097  globCounter++ ;
1098  if (!ws().arg(autoname.c_str())) {
1099  break ;
1100  }
1101  }
1102  autoname = Form("%s::%s",func.c_str(),autoname.c_str()) ;
1103  }
1104  ret= processCreateArg(autoname,args) ;
1105  } else {
1106  coutE(ObjectHandling) << "RooFactoryWSTool::processSingleExpression(" << arg << "): ERROR: Syntax error: expect either Class(...) or Instance[...]" << endl ;
1107  logError() ;
1108  }
1109  } else {
1110  if (lb=='(') {
1111  // Process meta function (compile arguments, but not meta-function itself)
1112  ret= processMetaArg(func,args) ;
1113  } else {
1114  coutE(ObjectHandling) << "RooFactoryWSTool::processSingleExpression(" << arg << "): ERROR: Syntax error: $MetaClass must be followed by (...)" << endl ;
1115  logError() ;
1116  }
1117  }
1118 
1119  // Return reduced token with suffix
1120  return ret ;
1121 }
1122 
1123 
1124 ////////////////////////////////////////////////////////////////////////////////
1125 /// Process a list of high-level expression. The returned string a the reduced
1126 /// expression list where all inline object creations have been executed and substituted
1127 /// with the name of the created object
1128 ///
1129 /// E.g. '{x(-10,10),s} --> '{x,s}'
1130 
1132 {
1133  // Allocate and fill work buffer
1134  const size_t bufSize = strlen(arg)+1;
1135  char* buf = new char[bufSize] ;
1136  strlcpy(buf,arg,bufSize) ;
1137 
1138  vector<string> args ;
1139 
1140  // Start running pointer at position 1 to skip opening bracket
1141  char* tok = buf+1 ;
1142  char* p = buf+1 ;
1143 
1144  // Processing look
1145  Int_t level(0) ;
1146  while(*p) {
1147 
1148  // Track bracketing level
1149  if (*p=='{' || *p=='(' || *p=='[') level++ ;
1150  if (*p=='}' || *p==')' || *p==']') level-- ;
1151 
1152 
1153  // If we encounter a comma at zero bracket level
1154  // finalize the current token as a completed argument
1155  // and start the next token
1156  if (level==0 && ((*p)==',')) {
1157  *p = 0 ;
1158  args.push_back(tok) ;
1159  tok = p+1 ;
1160  }
1161 
1162  p++ ;
1163  }
1164 
1165  // Finalize token as last argument
1166  if (p>buf && *(p-1)=='}') {
1167  *(p-1)=0 ;
1168  }
1169  args.push_back(tok) ;
1170 
1171  // Delete work buffer
1172  delete[] buf ;
1173 
1174  // Process each argument in list and construct reduced
1175  // expression to be returned
1176  string ret("{") ;
1177  vector<string>::iterator iter = args.begin() ;
1178  Int_t i(0) ;
1179  while(iter!= args.end()) {
1180  if (strlen(ret.c_str())>1) ret += "," ;
1181  if (!_autoNamePrefix.empty()) {
1182  _autoNamePrefix.push(Form("%s%d",_autoNamePrefix.top().c_str(),i+1)) ;
1183  }
1184  ret += processSingleExpression(iter->c_str()) ;
1185  if (!_autoNamePrefix.empty()) {
1186  _autoNamePrefix.pop() ;
1187  }
1188  iter++ ;
1189  i++ ;
1190  }
1191  ret += "}" ;
1192 
1193  return ret ;
1194 }
1195 
1196 
1197 
1198 ////////////////////////////////////////////////////////////////////////////////
1199 /// Parse token
1200 
1202 {
1203  vector<string> args = splitFunctionArgs(token) ;
1204  if (args.size()!=2) {
1205  coutE(ObjectHandling) << "RooFactorWSTool::processAliasExpression() ERROR $Alias() takes exactly two arguments, " << args.size() << " args found" << endl ;
1206  logError() ;
1207  return string() ;
1208  }
1209 
1210  // Insert alias in table
1211  _typeAliases[args[1]] = args[0] ;
1212 
1213  return string() ;
1214 }
1215 
1216 
1217 
1218 
1219 ////////////////////////////////////////////////////////////////////////////////
1220 
1222 {
1223  // First do recursive alias expansion
1224  while (true) {
1225  map<string,string>::iterator item = _typeAliases.find(className) ;
1226 
1227  // If an alias is found, recurse
1228  if (item != _typeAliases.end()) {
1229  className = item->second.c_str() ;
1230  } else {
1231  break ;
1232  }
1233  }
1234 
1235  // Now find dealiased class in ROOT class table
1236  TClass* tc = TClass::GetClass(className,kTRUE,kTRUE) ;
1237 
1238  // If its not there, try prefixing with Roo
1239  if (!tc) {
1240  tc = TClass::GetClass(Form("Roo%s",className)) ;
1241  if (!tc) {
1242  coutE(ObjectHandling) << "RooFactoryWSTool::createArg() ERROR class " << className << " not defined in ROOT class table" << endl ;
1243  logError() ;
1244  return 0 ;
1245  }
1246  }
1247  return tc ;
1248 }
1249 
1250 
1251 
1252 ////////////////////////////////////////////////////////////////////////////////
1253 
1254 string RooFactoryWSTool::varTag(string& func, vector<string>& args)
1255 {
1256  string ret ;
1257  ret += func ;
1258  ret += "[" ;
1259  for (vector<string>::iterator iter = args.begin() ; iter!=args.end() ; ++iter) {
1260  if (iter!=args.begin()) {
1261  ret += "," ;
1262  }
1263  ret += *iter ;
1264  }
1265  ret += "]" ;
1266  return ret ;
1267 }
1268 
1269 
1270 
1271 
1272 ////////////////////////////////////////////////////////////////////////////////
1273 /// Glue function between high-level syntax and low-level factory call to createVariable:
1274 /// Process a parsed call to create a variable named 'func'
1275 ///
1276 /// If initial token is non-numeric, a RooCategory will be created, and the args are interpreted
1277 /// as either state names or 'name=id' assignments. Otherwise a RooRealvar is created and the
1278 /// arg list is interpreted as follows:
1279 /// If list has two args, these are interpreted as xmin,xmax
1280 /// If list has three args, these are interpreted as xinit,xmin,xmax
1281 /// If list has one arg, this is interpreted as xinit and the variable is set as constant
1282 
1283 string RooFactoryWSTool::processCreateVar(string& func, vector<string>& args)
1284 {
1285 
1286  // Determine if first arg is numeric
1287  string first = *(args.begin()) ;
1288  if (isdigit(first[0]) || first[0]=='.' || first[0]=='+' || first[0]=='-') {
1289 
1290  // Create a RooRealVar
1291  vector<string>::iterator ai = args.begin() ;
1292  if (args.size()==1) {
1293 
1294  // One argument, create constant variable with given value
1295  Double_t xinit = atof((ai)->c_str()) ;
1296  cxcoutD(ObjectHandling) << "CREATE variable " << func << " xinit = " << xinit << endl ;
1297  RooRealVar tmp(func.c_str(),func.c_str(),xinit) ;
1298  tmp.setStringAttribute("factory_tag",varTag(func,args).c_str()) ;
1299  if (_ws->import(tmp,Silence())) {
1300  logError() ;
1301  }
1302 
1303  } else if (args.size()==2) {
1304 
1305  // Two arguments, create variable with given range
1306  Double_t xlo = atof((ai++)->c_str()) ;
1307  Double_t xhi = atof(ai->c_str()) ;
1308  cxcoutD(ObjectHandling) << "CREATE variable " << func << " xlo = " << xlo << " xhi = " << xhi << endl ;
1309  RooRealVar tmp(func.c_str(),func.c_str(),xlo,xhi) ;
1310  tmp.setStringAttribute("factory_tag",varTag(func,args).c_str()) ;
1311  if (_ws->import(tmp,Silence())) {
1312  logError() ;
1313  }
1314 
1315  } else if (args.size()==3) {
1316 
1317  // Three arguments, create variable with given initial value and range
1318  Double_t xinit = atof((ai++)->c_str()) ;
1319  Double_t xlo = atof((ai++)->c_str()) ;
1320  Double_t xhi = atof(ai->c_str()) ;
1321  cxcoutD(ObjectHandling) << "CREATE variable " << func << " xinit = " << xinit << " xlo = " << xlo << " xhi = " << xhi << endl ;
1322  RooRealVar tmp(func.c_str(),func.c_str(),xinit,xlo,xhi) ;
1323  tmp.setStringAttribute("factory_tag",varTag(func,args).c_str()) ;
1324  if (_ws->import(tmp,Silence())) {
1325  logError() ;
1326  }
1327  }
1328  } else {
1329 
1330  // Create a RooAbsCategory
1331  string allStates ;
1332  for (vector<string>::iterator ai = args.begin() ; ai!=args.end() ; ai++) {
1333  if (allStates.size()>0) {
1334  allStates += "," ;
1335  }
1336  allStates += *ai ;
1337  }
1338  createCategory(func.c_str(),allStates.c_str()) ;
1339 
1340  }
1341  return func ;
1342 }
1343 
1344 
1345 ////////////////////////////////////////////////////////////////////////////////
1346 /// Glue function between high-level syntax and low-level factory call to createArg:
1347 /// Process a parsed call to create a p.d.f named func
1348 ///
1349 /// The func arg is interpreted as ClassName::ObjectName and the arglist is passed
1350 /// verbatim to createArg. The received arglist is expected to be fully reduced (i.e.
1351 /// all inline object creations must have been compiled)
1352 
1353 string RooFactoryWSTool::processCreateArg(string& func, vector<string>& args)
1354 {
1355  // Allocate and fill work buffer
1356  char buf[BUFFER_SIZE] ;
1357  strlcpy(buf,func.c_str(),BUFFER_SIZE) ;
1358 
1359  // Split function part in class name and instance name
1360  char* save ;
1361  const char *className = strtok_r(buf,":",&save) ;
1362  const char *instName = strtok_r(0,":",&save) ;
1363  if (!className) className = "";
1364  if (!instName) instName = "" ;
1365 
1366  // Concatenate list of args into comma separated string
1367  char pargs[BUFFER_SIZE] ;
1368  pargs[0] = 0 ;
1369  vector<string>::iterator iter = args.begin() ;
1370  vector<string> pargv ;
1371  Int_t iarg(0) ;
1372  while(iter!=args.end()) {
1373  if (strlen(pargs)>0) strlcat(pargs,",",BUFFER_SIZE) ;
1374  _autoNamePrefix.push(Form("%s_%d",instName,iarg+1)) ;
1375  string tmp = processExpression(iter->c_str()) ;
1376  _autoNamePrefix.pop() ;
1377  strlcat(pargs,tmp.c_str(),BUFFER_SIZE) ;
1378  pargv.push_back(tmp) ;
1379  iter++ ;
1380  iarg++ ;
1381  }
1382 
1383  // Look up if func is a special
1384  for (map<string,IFace*>::iterator ii=hooks().begin() ; ii!=hooks().end() ; ii++) {
1385  }
1386  if (hooks().find(className) != hooks().end()) {
1387  IFace* iface = hooks()[className] ;
1388  return iface->create(*this, className,instName,pargv) ;
1389  }
1390 
1391  createArg(className,instName,pargs) ;
1392 
1393  return string(instName) ;
1394 }
1395 
1396 
1397 
1398 ////////////////////////////////////////////////////////////////////////////////
1399 /// Concatenate list of args into comma separated string
1400 
1401 std::string RooFactoryWSTool::processMetaArg(std::string& func, std::vector<std::string>& args)
1402 {
1403  char pargs[BUFFER_SIZE] ;
1404  pargs[0] = 0 ;
1405  vector<string>::iterator iter = args.begin() ;
1406  vector<string> pargv ;
1407  while(iter!=args.end()) {
1408  if (strlen(pargs)>0) strlcat(pargs,",",BUFFER_SIZE) ;
1409  string tmp = processExpression(iter->c_str()) ;
1410  strlcat(pargs,tmp.c_str(),BUFFER_SIZE) ;
1411  pargv.push_back(tmp) ;
1412  iter++ ;
1413  }
1414 
1415  string ret = func+"("+pargs+")" ;
1416  return ret ;
1417 }
1418 
1419 
1420 
1421 
1422 ////////////////////////////////////////////////////////////////////////////////
1423 /// Allocate and fill work buffer
1424 
1425 vector<string> RooFactoryWSTool::splitFunctionArgs(const char* funcExpr)
1426 {
1427  const size_t bufSize = strlen(funcExpr)+1;
1428  char* buf = new char[bufSize] ;
1429  strlcpy(buf,funcExpr,bufSize) ;
1430  char* bufptr = buf ;
1431 
1432  string func ;
1433  vector<string> args ;
1434 
1435  // Process token into arguments
1436  char* save ;
1437  char* tmpx = strtok_r(buf,"(",&save) ;
1438  func = tmpx ? tmpx : "" ;
1439  char* p = strtok_r(0,"",&save) ;
1440 
1441  // Return here if token is fundamental
1442  if (!p) {
1443  delete[] buf ;
1444  return args ;
1445  }
1446 
1447  char* tok = p ;
1448  Int_t blevel=0 ;
1449  Bool_t litmode(kFALSE) ;
1450  while(*p) {
1451 
1452  // Keep track of opening and closing brackets
1453  if (*p=='{' || *p=='(' || *p=='[') blevel++ ;
1454  if (*p=='}' || *p==')' || *p==']') blevel-- ;
1455 
1456  // Keep track of string literals
1457  if (*p=='"' || *p=='\'') litmode = !litmode ;
1458 
1459 
1460  // If we encounter a comma at zero bracket level
1461  // finalize the current token as a completed argument
1462  // and start the next token
1463  if (!litmode && blevel==0 && ((*p)==',')) {
1464  *p = 0 ;
1465  args.push_back(tok) ;
1466  tok = p+1 ;
1467  }
1468 
1469  p++ ;
1470  }
1471 
1472  // If the last character was a closing bracket, kill
1473  // it in the buffer
1474  if (p>bufptr && *(p-1)==')') {
1475  *(p-1)=0 ;
1476  }
1477 
1478  // Finalize last token as argument
1479  string tmp = tok ;
1480 
1481  // If there is a suffix left in the work buffer attach it to
1482  // this argument
1483  p = strtok_r(0,"",&save) ;
1484  if (p) tmp += p ;
1485  args.push_back(tmp) ;
1486 
1487  // Delete the work buffer
1488  delete[] buf ;
1489 
1490  return args ;
1491 }
1492 
1493 
1494 
1495 
1496 
1497 ////////////////////////////////////////////////////////////////////////////////
1498 /// Perform basic syntax on given factory expression. If function returns
1499 /// true syntax errors are found.
1500 
1502 {
1503  // Count parentheses
1504  Int_t nParentheses(0), nBracket(0), nAccolade(0) ;
1505  const char* ptr = arg ;
1506  while(*ptr) {
1507  if (*ptr=='(') nParentheses++ ;
1508  if (*ptr==')') nParentheses-- ;
1509  if (*ptr=='[') nBracket++ ;
1510  if (*ptr==']') nBracket-- ;
1511  if (*ptr=='{') nAccolade++ ;
1512  if (*ptr=='}') nAccolade-- ;
1513  ptr++ ;
1514  }
1515  if (nParentheses!=0) {
1516  coutE(ObjectHandling) << "RooFactoryWSTool::checkSyntax ERROR non-matching '" << (nParentheses>0?"(":")") << "' in expression" << endl ;
1517  return kTRUE ;
1518  }
1519  if (nBracket!=0) {
1520  coutE(ObjectHandling) << "RooFactoryWSTool::checkSyntax ERROR non-matching '" << (nBracket>0?"[":"]") << "' in expression" << endl ;
1521  return kTRUE ;
1522  }
1523  if (nAccolade!=0) {
1524  coutE(ObjectHandling) << "RooFactoryWSTool::checkSyntax ERROR non-matching '" << (nAccolade>0?"{":"}") << "' in expression" << endl ;
1525  return kTRUE ;
1526  }
1527  return kFALSE ;
1528 }
1529 
1530 
1531 
1532 ////////////////////////////////////////////////////////////////////////////////
1533 
1535 {
1536  if (idx>_of->_args.size()-1) {
1537  throw string(Form("Need argument number %d, but only %d args are provided",idx,(Int_t)_of->_args.size())) ;
1538  }
1539 }
1540 
1541 
1542 
1543 ////////////////////////////////////////////////////////////////////////////////
1544 /// CINT constructor interface, return constructor string argument #idx as RooAbsArg reference found in workspace
1545 
1547  {
1548  // If arg is a numeric string, make a RooConst() of it here
1549  if (arg[0]=='.' || arg[0]=='+' || arg[0] == '-' || isdigit(arg[0])) {
1550  return RooConst(atof(arg)) ;
1551  }
1552 
1553  // Otherwise look it up by name in the workspace
1554  RooAbsArg* rarg = ws().arg(arg) ;
1555  if (!rarg) {
1556  throw string(Form("RooAbsArg named %s not found",arg)) ;
1557  }
1558  return *rarg ;
1559 }
1560 
1561 
1562 
1563 ////////////////////////////////////////////////////////////////////////////////
1564 /// CINT constructor interface, return constructor string argument #idx as RooAbsReal reference found in workspace
1565 
1567 {
1568  // If arg is a numeric string, make a RooConst() of it here
1569  if (arg[0]=='.' || arg[0]=='+' || arg[0] == '-' || isdigit(arg[0])) {
1570  return RooConst(atof(arg)) ;
1571  }
1572 
1573  RooAbsArg* rarg = ws().arg(arg) ;
1574  if (!rarg) {
1575  throw string(Form("RooAbsReal named %s not found",arg)) ;
1576  }
1577  RooAbsReal* real = dynamic_cast<RooAbsReal*>(rarg) ;
1578  if (!real) {
1579  throw string(Form("Object named %s is not of type RooAbsReal",arg)) ;
1580  }
1581  return *real ;
1582 }
1583 
1584 
1585 
1586 ////////////////////////////////////////////////////////////////////////////////
1587 /// CINT constructor interface, return constructor string argument #idx as RooAbsRealLValue reference found in workspace
1588 
1590 {
1591  // If arg is a numeric string, throw error as lvalue is required
1592  if (arg[0]=='.' || arg[0]=='+' || arg[0] == '-' || isdigit(arg[0])) {
1593  throw string(Form("Numeric literal provided for argument (%s), but lvalue is required",arg)) ;
1594  }
1595 
1596  RooAbsArg* rarg = ws().arg(arg) ;
1597  if (!rarg) {
1598  throw string(Form("RooAbsRealLValue named %s not found",arg)) ;
1599  }
1600  RooAbsRealLValue* reallv = dynamic_cast<RooAbsRealLValue*>(rarg) ;
1601  if (!reallv) {
1602  throw string(Form("Object named %s is not of type RooAbsRealLValue",arg)) ;
1603  }
1604  return *reallv ;
1605 }
1606 
1607 
1608 
1609 ////////////////////////////////////////////////////////////////////////////////
1610 /// CINT constructor interface, return constructor string argument #idx as RooRealVar reference found in workspace
1611 
1613 {
1614  RooRealVar* var = ws().var(arg) ;
1615  if (!var) {
1616  throw string(Form("RooRealVar named %s not found",arg)) ;
1617  }
1618  return *var ;
1619 }
1620 
1621 
1622 
1623 
1624 ////////////////////////////////////////////////////////////////////////////////
1625 /// CINT constructor interface, return constructor string argument #idx as RooAbsPdf reference found in workspace
1626 
1628 {
1629  RooAbsPdf* pdf = ws().pdf(arg) ;
1630  if (!pdf) {
1631  throw string(Form("RooAbsPdf named %s not found",arg)) ;
1632  }
1633  return *pdf ;
1634 }
1635 
1636 
1637 
1638 
1639 ////////////////////////////////////////////////////////////////////////////////
1640 /// CINT constructor interface, return constructor string argument #idx as RooResolutionModel reference found in workspace
1641 
1643 {
1644  RooAbsArg* rarg = ws().arg(arg) ;
1645  if (!rarg) {
1646  throw string(Form("RooResolutionModel named %s not found",arg)) ;
1647  }
1648  RooResolutionModel * rmodel = dynamic_cast<RooResolutionModel*>(rarg) ;
1649  if (!rmodel) {
1650  throw string(Form("Object named %s is not of type RooResolutionModel",arg)) ;
1651  }
1652  return *rmodel ;
1653 }
1654 
1655 
1656 
1657 
1658 ////////////////////////////////////////////////////////////////////////////////
1659 /// CINT constructor interface, return constructor string argument #idx as RooAbsCategory reference found in workspace
1660 
1662 {
1663  RooAbsArg* rarg = ws().arg(arg) ;
1664  if (!rarg) {
1665  throw string(Form("RooAbsCategory named %s not found",arg)) ;
1666  }
1667  RooAbsCategory* catf = dynamic_cast<RooAbsCategory*>(rarg) ;
1668  if (!catf) {
1669  throw string(Form("Object named %s is not of type RooAbsCategory",arg)) ;
1670  }
1671  return *catf ;
1672 }
1673 
1674 
1675 
1676 ////////////////////////////////////////////////////////////////////////////////
1677 /// CINT constructor interface, return constructor string argument #idx as RooAbsCategoryLValue reference found in workspace
1678 
1680 {
1681  RooAbsArg* rarg = ws().arg(arg) ;
1682  if (!rarg) {
1683  throw string(Form("RooAbsCategoryLValue named %s not found",arg)) ;
1684  }
1685 
1686  RooAbsCategoryLValue* catlv = dynamic_cast<RooAbsCategoryLValue*>(rarg) ;
1687  if (!catlv) {
1688  throw string(Form("Object named %s is not of type RooAbsCategoryLValue",arg)) ;
1689  }
1690  return *catlv ;
1691 }
1692 
1693 
1694 
1695 ////////////////////////////////////////////////////////////////////////////////
1696 /// CINT constructor interface, return constructor string argument #idx as RooCategory reference found in workspace
1697 
1699 {
1700  RooCategory* cat = ws().cat(arg) ;
1701  if (!cat) {
1702  throw string(Form("RooCategory named %s not found",arg)) ;
1703  }
1704  return *cat ;
1705 }
1706 
1707 
1708 
1709 
1710 
1711 ////////////////////////////////////////////////////////////////////////////////
1712 /// CINT constructor interface, return constructor string argument #idx as RooArgSet of objects found in workspace
1713 
1715 {
1716  char tmp[BUFFER_SIZE] ;
1717  strlcpy(tmp,arg,BUFFER_SIZE) ;
1718 
1719  RooArgSet s ;
1720 
1721  // If given object is not of {,,,} form, interpret given string as name of defined set
1722  if (arg[0]!='{') {
1723  // cout << "asSet(arg='" << arg << "') parsing as defined set" << endl ;
1724  const RooArgSet* defSet = ws().set(arg) ;
1725  if (defSet) {
1726  // cout << "found defined set: " << *defSet << endl ;
1727  s.add(*defSet) ;
1728  return s ;
1729  }
1730  }
1731 
1732  char* save ;
1733  char* tok = strtok_r(tmp,",{}",&save) ;
1734  while(tok) {
1735 
1736  // If arg is a numeric string, make a RooConst() of it here
1737  if (tok[0]=='.' || tok[0]=='+' || tok[0] == '-' || isdigit(tok[0])) {
1738  s.add(RooConst(atof(tok))) ;
1739  } else {
1740  RooAbsArg* aarg = ws().arg(tok) ;
1741  if (aarg) {
1742  s.add(*aarg) ;
1743  } else {
1744  throw string(Form("RooAbsArg named %s not found",tok)) ;
1745  }
1746  }
1747  tok = strtok_r(0,",{}",&save) ;
1748  }
1749 
1750  return s ;
1751 }
1752 
1753 
1754 
1755 ////////////////////////////////////////////////////////////////////////////////
1756 /// CINT constructor interface, return constructor string argument #idx as RooArgList of objects found in workspace
1757 
1759 {
1760  char tmp[BUFFER_SIZE] ;
1761  strlcpy(tmp,arg,BUFFER_SIZE) ;
1762 
1763  RooArgList l ;
1764  char* save ;
1765  char* tok = strtok_r(tmp,",{}",&save) ;
1766  while(tok) {
1767 
1768  // If arg is a numeric string, make a RooConst() of it here
1769  if (tok[0]=='.' || tok[0]=='+' || tok[0] == '-' || isdigit(tok[0])) {
1770  l.add(RooConst(atof(tok))) ;
1771  } else {
1772  RooAbsArg* aarg = ws().arg(tok) ;
1773  if (aarg) {
1774  l.add(*aarg) ;
1775  } else {
1776  throw string(Form("RooAbsArg named %s not found",tok)) ;
1777  }
1778  }
1779  tok = strtok_r(0,",{}",&save) ;
1780  }
1781 
1782  return l ;
1783 }
1784 
1785 
1786 
1787 ////////////////////////////////////////////////////////////////////////////////
1788 /// CINT constructor interface, return constructor string argument #idx as RooAbsData object found in workspace
1789 
1791 {
1792  RooAbsData* data = ws().data(arg) ;
1793  if (!data) {
1794  throw string(Form("RooAbsData named %s not found",arg)) ;
1795  }
1796  return *data ;
1797 }
1798 
1799 
1800 
1801 ////////////////////////////////////////////////////////////////////////////////
1802 /// CINT constructor interface, return constructor string argument #idx as RooDataHist object found in workspace
1803 
1805 {
1806  RooAbsData* data = ws().data(arg) ;
1807  if (!data) {
1808  throw string(Form("RooAbsData named %s not found",arg)) ;
1809  }
1810  RooDataHist* hist = dynamic_cast<RooDataHist*>(data) ;
1811  if (!hist) {
1812  throw string(Form("Dataset named %s is not of type RooDataHist",arg)) ;
1813  }
1814  return *hist ;
1815 }
1816 
1817 
1818 ////////////////////////////////////////////////////////////////////////////////
1819 /// CINT constructor interface, return constructor string argument #idx as RooDataSet object found in workspace
1820 
1822 {
1823  RooAbsData* data = ws().data(arg) ;
1824  if (!data) {
1825  throw string(Form("RooAbsData named %s not found",arg)) ;
1826  }
1827  RooDataSet* dset = dynamic_cast<RooDataSet*>(data) ;
1828  if (!dset) {
1829  throw string(Form("Dataset named %s is not of type RooDataSet",arg)) ;
1830  }
1831  return *dset ;
1832 }
1833 
1834 
1835 
1836 ////////////////////////////////////////////////////////////////////////////////
1837 
1839 {
1840  TObject* obj = ws().obj(arg) ;
1841  if (!obj) {
1842  throw string(Form("Object named %s not found",arg)) ;
1843  }
1844  return *obj ;
1845 }
1846 
1847 
1848 
1849 ////////////////////////////////////////////////////////////////////////////////
1850 /// CINT constructor interface, return constructor string argument #idx as const char*
1851 
1852 const char* RooFactoryWSTool::asSTRING(const char* arg)
1853 {
1854  static vector<string> cbuf(10) ;
1855  static unsigned int cbuf_idx = 0 ;
1856 
1857  // Handle empty string case: return null pointer
1858  if (arg==0 || strlen(arg)==0) {
1859  return 0 ;
1860  }
1861 
1862  // Fill cyclical buffer entry with quotation marked stripped version of string literal
1863  // and return pointer to stripped buffer
1864  cbuf[cbuf_idx].clear() ;
1865  const char* p = arg+1 ;
1866  while(*p && (*p) != '"' && (*p) !='\'' ) {
1867  cbuf[cbuf_idx] += *(p++) ;
1868  }
1869  const char* ret = cbuf[cbuf_idx].c_str() ;
1870 
1871  // Increment buffer pointer by one
1872  cbuf_idx++ ;
1873  if (cbuf_idx==cbuf.size()) cbuf_idx=0 ;
1874 
1875  return ret ;
1876 }
1877 
1878 
1879 ////////////////////////////////////////////////////////////////////////////////
1880 /// CINT constructor interface, return constructor string argument #idx as Int_t
1881 
1883 {
1884  return atoi(arg) ;
1885 }
1886 
1887 
1888 ////////////////////////////////////////////////////////////////////////////////
1889 /// CINT constructor interface, return constructor string argument #idx as Double_t
1890 
1892 {
1893  return atof(arg) ;
1894 }
1895 
1896 
1897 ////////////////////////////////////////////////////////////////////////////////
1898 /// Register foreign special objects in factory
1899 
1901 {
1902  hooks()[typeName] = iface ;
1903 }
1904 
1905 
1906 
1907 ////////////////////////////////////////////////////////////////////////////////
1908 
1909 std::map<std::string,RooFactoryWSTool::IFace*>& RooFactoryWSTool::hooks()
1910 {
1911  if (_hooks) return *_hooks ;
1912  _hooks = new map<string,IFace*> ;
1913  return *_hooks ;
1914 }
1915 
1916 
1917 
1918 ////////////////////////////////////////////////////////////////////////////////
1919 /// Concatenate list of args into comma separated string
1920 
1921 std::string RooFactoryWSTool::SpecialsIFace::create(RooFactoryWSTool& ft, const char* typeName, const char* instName, std::vector<std::string> args)
1922 {
1923  char pargs[BUFFER_SIZE] ;
1924  pargs[0] = 0 ;
1925  vector<string>::iterator iter = args.begin() ;
1926  vector<string> pargv ;
1927  while(iter!=args.end()) {
1928  if (strlen(pargs)>0) strlcat(pargs,",",BUFFER_SIZE) ;
1929  string tmp = ft.processExpression(iter->c_str()) ;
1930  strlcat(pargs,tmp.c_str(),BUFFER_SIZE) ;
1931  pargv.push_back(tmp) ;
1932  iter++ ;
1933  }
1934 
1935  // Handling of special operator pdf class names
1936  string cl(typeName) ;
1937  if (cl=="SUM") {
1938 
1939  // SUM::name[a*A,b*B,C]
1940  ft.add(instName,pargs,kFALSE) ;
1941 
1942  } else if (cl=="RSUM") {
1943 
1944  // RSUM::name[a*A,b*B,C]
1945  ft.add(instName,pargs,kTRUE) ;
1946 
1947  } else if (cl=="ASUM") {
1948 
1949  // ASUM::name[a*A,b*B,C]
1950  ft.amplAdd(instName,pargs) ;
1951 
1952  } else if (cl=="PROD") {
1953 
1954  // PROD::name[A,B,C]
1955  ft.prod(instName,pargs) ;
1956 
1957  } else if (cl=="SIMUL") {
1958 
1959  // PROD::name[cat,state=Pdf,...]
1960  if (pargv.size()>1) {
1961  ft.simul(instName,pargv[0].c_str(),strchr(pargs,',')+1) ;
1962  } else {
1963  throw string(Form("Need at least two arguments in call to SIMUL::%s, have %d: %s",instName,(Int_t)pargv.size(),pargs)) ;
1964  }
1965 
1966  } else if (cl=="EXPR") {
1967 
1968  // EXPR::name['expr',var,var,...]
1969  if (args.size()<=2) {
1970  ft.createArg("RooGenericPdf",instName,pargs) ;
1971  } else {
1972  char genargs[BUFFER_SIZE] ;
1973  strlcpy(genargs,args[0].c_str(),BUFFER_SIZE) ;
1974  strlcat(genargs,",{",BUFFER_SIZE) ;
1975  for (UInt_t i=1 ; i<args.size() ; i++) {
1976  if (i!=1) strlcat(genargs,",",BUFFER_SIZE) ;
1977  strlcat(genargs,args[i].c_str(),BUFFER_SIZE) ;
1978  }
1979  strlcat(genargs,"}",BUFFER_SIZE) ;
1980  ft.createArg("RooGenericPdf",instName,genargs) ;
1981  }
1982 
1983  } else if (cl=="FCONV") {
1984 
1985  // FCONV::name[var,pdf1,pdf2]
1986  ft.createArg("RooFFTConvPdf",instName,pargs) ;
1987 
1988  } else if (cl=="NCONV") {
1989 
1990  // NCONV::name[var,pdf1,pdf2]
1991  ft.createArg("RooNumConvPdf",instName,pargs) ;
1992 
1993  } else if (cl=="sum") {
1994 
1995  // sum::name[a,b,c]
1996  ft.addfunc(instName,pargs) ;
1997 
1998  } else if (cl=="prod") {
1999 
2000  // prod::name[a,b,c]
2001  ft.prodfunc(instName,pargs) ;
2002 
2003  } else if (cl=="expr") {
2004 
2005  // expr::name['expr',var,var,...]
2006  if (args.size()<=2) {
2007  ft.createArg("RooFormulaVar",instName,pargs) ;
2008  } else {
2009  char genargs[BUFFER_SIZE] ;
2010  strlcpy(genargs,args[0].c_str(),BUFFER_SIZE) ;
2011  strlcat(genargs,",{",BUFFER_SIZE) ;
2012  for (UInt_t i=1 ; i<args.size() ; i++) {
2013  if (i!=1) strlcat(genargs,",",BUFFER_SIZE) ;
2014  strlcat(genargs,args[i].c_str(),BUFFER_SIZE) ;
2015  }
2016  strlcat(genargs,"}",BUFFER_SIZE) ;
2017  ft.createArg("RooFormulaVar",instName,genargs) ;
2018  }
2019 
2020  } else if (cl=="nconv") {
2021 
2022  // nconv::name[var,pdf1,pdf2]
2023  ft.createArg("RooNumConvolution",instName,pargs) ;
2024 
2025  } else if (cl=="nll") {
2026 
2027  // nll::name[pdf,data]
2028  RooNLLVar nll(instName,instName,ft.asPDF(pargv[0].c_str()),ft.asDATA(pargv[1].c_str())) ;
2029  if (ft.ws().import(nll,Silence())) ft.logError() ;
2030 
2031  } else if (cl=="chi2") {
2032 
2033  // chi2::name[pdf,data]
2034  RooChi2Var nll(instName,instName,ft.asPDF(pargv[0].c_str()),ft.asDHIST(pargv[1].c_str())) ;
2035  if (ft.ws().import(nll,Silence())) ft.logError() ;
2036 
2037  } else if (cl=="profile") {
2038 
2039  // profile::name[func,vars]
2040  ft.createArg("RooProfileLL",instName,pargs) ;
2041 
2042  } else if (cl=="dataobs") {
2043 
2044  // dataobs::name[dset,func]
2045  RooAbsArg* funcClone = static_cast<RooAbsArg*>(ft.asARG(pargv[1].c_str()).clone(instName)) ;
2046  RooAbsArg* arg = ft.asDSET(pargv[0].c_str()).addColumn(*funcClone) ;
2047  if (!ft.ws().fundArg(arg->GetName())) {
2048  if (ft.ws().import(*arg,Silence())) ft.logError() ;
2049  }
2050  delete funcClone ;
2051 
2052  } else if (cl=="int") {
2053 
2054  // int::name[func,intobs]
2055  // int::name[func,intobs|range]
2056  // int::name[func,intobs,normobs]
2057  // int::name[func,intobs|range,normobs]
2058 
2059  if (pargv.size()<2 || pargv.size()>3) {
2060  throw string(Form("int::%s, requires 2 or 3 arguments, have %d arguments",instName,(Int_t)pargv.size())) ;
2061  }
2062 
2063  RooAbsReal& func = ft.asFUNC(pargv[0].c_str()) ;
2064 
2065  char buf[256] ;
2066  strlcpy(buf,pargv[1].c_str(),256) ;
2067  char* save ;
2068  const char* intobs = strtok_r(buf,"|",&save) ;
2069  if (!intobs) intobs="" ;
2070 
2071  const char* range = strtok_r(0,"",&save) ;
2072  if (!range) range="" ;
2073 
2074  RooAbsReal* integral = 0 ;
2075  if (pargv.size()==2) {
2076  if (range && strlen(range)) {
2077  integral = func.createIntegral(ft.asSET(intobs),Range(range)) ;
2078  } else {
2079  integral = func.createIntegral(ft.asSET(intobs)) ;
2080  }
2081  } else {
2082  if (range && strlen(range)) {
2083  integral = func.createIntegral(ft.asSET(intobs),Range(range),NormSet(ft.asSET(pargv[2].c_str()))) ;
2084  } else {
2085  integral = func.createIntegral(ft.asSET(intobs),NormSet(ft.asSET(pargv[2].c_str()))) ;
2086  }
2087  }
2088 
2089  integral->SetName(instName) ;
2090  if (ft.ws().import(*integral,Silence())) ft.logError() ;
2091 
2092  } else if (cl=="deriv") {
2093 
2094  // derive::name[func,obs,order]
2095 
2096  if (pargv.size()<2 || pargv.size()>3) {
2097  throw string(Form("deriv::%s, requires 2 or 3 arguments, have %d arguments",instName,(Int_t)pargv.size())) ;
2098  }
2099 
2100  RooAbsReal& func = ft.asFUNC(pargv[0].c_str()) ;
2101 
2102  RooAbsReal* derivative(0) ;
2103  if (pargv.size()==2) {
2104  derivative = func.derivative(ft.asVAR(pargv[1].c_str()),1) ;
2105  } else {
2106  derivative = func.derivative(ft.asVAR(pargv[1].c_str()),ft.asINT(pargv[2].c_str())) ;
2107  }
2108 
2109  derivative->SetName(instName) ;
2110  if (ft.ws().import(*derivative,Silence())) ft.logError() ;
2111 
2112  } else if (cl=="cdf") {
2113 
2114  // cdf::name[pdf,obs,extranormobs]
2115 
2116  if (pargv.size()<2 || pargv.size()>3) {
2117  throw string(Form("cdf::%s, requires 2 or 3 arguments, have %d arguments",instName,(Int_t)pargv.size())) ;
2118  }
2119 
2120  RooAbsPdf& pdf = ft.asPDF(pargv[0].c_str()) ;
2121 
2122  RooAbsReal* cdf(0) ;
2123  if (pargv.size()==2) {
2124  cdf = pdf.createCdf(ft.asSET(pargv[1].c_str())) ;
2125  } else {
2126  cdf = pdf.createCdf(ft.asSET(pargv[1].c_str()),ft.asSET(pargv[2].c_str())) ;
2127  }
2128 
2129  cdf->SetName(instName) ;
2130  if (ft.ws().import(*cdf,Silence())) ft.logError() ;
2131 
2132 
2133  } else if (cl=="PROJ") {
2134 
2135  // PROJ::name(pdf,intobs)
2136  if (pargv.size()!=2) {
2137  throw string(Form("PROJ::%s, requires 2 arguments, have %d arguments",instName,(Int_t)pargv.size())) ;
2138  }
2139 
2140  RooAbsPdf& pdf = ft.asPDF(pargv[0].c_str()) ;
2141  RooAbsPdf* projection = pdf.createProjection(ft.asSET(pargv[1].c_str())) ;
2142  projection->SetName(instName) ;
2143 
2144  if (ft.ws().import(*projection,Silence())) ft.logError() ;
2145 
2146  } else if (cl=="set") {
2147 
2148  // set::name(arg,arg,...)
2149  if (ft.ws().defineSet(instName,pargs)) {
2150  ft.logError() ;
2151  return string(instName) ;
2152  }
2153 
2154  } else {
2155 
2156  throw string(Form("RooFactoryWSTool::SpecialsIFace::create() ERROR: Unknown meta-type %s",typeName)) ;
2157 
2158  }
2159  return string(instName) ;
2160 }
2161 
2162 
2164 {
2165  return _of ;
2166 }
2167 
virtual TObject * clone(const char *newname=0) const =0
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
RooRealVar * createVariable(const char *name, Double_t xmin, Double_t xmax)
Low-level factory interface for creating a RooRealVar with a given range and initial value...
RooAddPdf is an efficient implementation of a sum of PDFs of the form.
Definition: RooAddPdf.h:29
std::string processSingleExpression(const char *arg)
Process a single high-level expression.
static RooResolutionModel & as_RMODEL(UInt_t idx)
static long int sum(long int i)
Definition: Factory.cxx:1786
#define coutE(a)
Definition: RooMsgService.h:35
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
float xmin
Definition: THbookFile.cxx:93
RooProduct * prodfunc(const char *objName, const char *pdfList)
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:86
Bool_t isValidEnumValue(const char *typeName, const char *value)
TObject & asOBJ(const char *)
std::vector< std::string > splitFunctionArgs(const char *funcExpr)
Allocate and fill work buffer.
Bool_t isEnum(const char *typeName)
RooArgList asLIST(const char *)
CINT constructor interface, return constructor string argument #idx as RooArgList of objects found in...
static RooRealVar & as_VAR(UInt_t idx)
RooAddPdf * add(const char *objName, const char *specList, Bool_t recursiveCoefs=kFALSE)
RooProdPdf is an efficient implementation of a product of PDFs of the form.
Definition: RooProdPdf.h:31
#define cxcoutD(a)
Definition: RooMsgService.h:80
RooWorkspace & ws()
static RooFactoryWSTool * _of
Bool_t cancelTransaction()
Cancel an ongoing import transaction.
RooCmdArg NormSet(const RooArgSet &nset)
RooFactoryWSTool is a clase like TTree::MakeClass() that generates skeleton code for RooAbsPdf and Ro...
RooSimultaneous * simul(const char *objName, const char *indexCat, const char *pdfMap)
static std::map< std::string, IFace * > & hooks()
#define BUFFER_SIZE
#define gROOT
Definition: TROOT.h:364
RooCmdArg Conditional(const RooArgSet &pdfSet, const RooArgSet &depSet, Bool_t depsAreCond=kFALSE)
static RooAbsCategoryLValue & as_CATLV(UInt_t idx)
static Double_t as_DOUBLE(UInt_t idx)
RooAbsCategory & asCATFUNC(const char *)
CINT constructor interface, return constructor string argument #idx as RooAbsCategory reference found...
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
RooAbsArg * fundArg(const char *name) const
Return fundamental (i.e.
RooRealSumPdf * amplAdd(const char *objName, const char *specList)
RooAbsArg * arg(const char *name) const
Return RooAbsArg with given name. A null pointer is returned if none is found.
STL namespace.
Class RooRealSumPdf implements a PDF constructed from a sum of functions:
Definition: RooRealSumPdf.h:24
const char * Class
Definition: TXMLSetup.cxx:64
static RooAbsData & as_DATA(UInt_t idx)
static RooArgSet as_SET(UInt_t idx)
static void checkIndex(UInt_t index)
std::map< std::string, std::string > _typeAliases
std::vector< std::string > _args
RooAbsReal * createCdf(const RooArgSet &iset, const RooArgSet &nset=RooArgSet())
Create a cumulative distribution function of this p.d.f in terms of the observables listed in iset...
Definition: RooAbsPdf.cxx:3027
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string &#39;value&#39; to this object under key &#39;key&#39;.
Definition: RooAbsArg.cxx:298
RooAbsArg * process(const char *expr)
Process high-level object creation syntax Accepted forms of syntax are.
std::pair< std::list< std::string >, unsigned int > ctorArgs(const char *classname, UInt_t nMinArgs=0)
static RooAbsRealLValue & as_VARLV(UInt_t idx)
const char * asSTRING(const char *)
CINT constructor interface, return constructor string argument #idx as const char*.
RooDataSet is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:40
virtual RooAbsArg * addColumn(RooAbsArg &var, Bool_t adjustRange=kTRUE)
Add a column with the values of the given (function) argument to this dataset.
Bool_t startTransaction()
Open an import transaction operations.
std::string varTag(std::string &func, std::vector< std::string > &args)
static RooAbsPdf & as_PDF(UInt_t idx)
RooResolutionModel & asRMODEL(const char *)
CINT constructor interface, return constructor string argument #idx as RooResolutionModel reference f...
static const std::string separator("@@@")
double cdf(double *x, double *p)
Definition: unuranDistr.cxx:44
static RooDataSet & as_DSET(UInt_t idx)
std::string processExpression(const char *expr)
Process a single high-level expression or list of expressions.
RooCmdArg Silence(Bool_t flag=kTRUE)
virtual RooAbsPdf * createProjection(const RooArgSet &iset)
Return a p.d.f that represent a projection of this p.d.f integrated over given observables.
Definition: RooAbsPdf.cxx:2989
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
RooCategory * cat(const char *name) const
Retrieve discrete variable (RooCategory) with given name. A null pointer is returned if not found...
std::string processAliasExpression(const char *arg)
Parse token.
static RooArgList as_LIST(UInt_t idx)
RooRealVar represents a fundamental (non-derived) real valued object.
Definition: RooRealVar.h:37
RooAbsArg & asARG(const char *)
CINT constructor interface, return constructor string argument #idx as RooAbsArg reference found in w...
RooAbsCategoryLValue & asCATLV(const char *)
CINT constructor interface, return constructor string argument #idx as RooAbsCategoryLValue reference...
std::string trueName(const char *typeDefName)
RooAbsData * data(const char *name) const
Retrieve dataset (binned or unbinned) with given name. A null pointer is returned if not found...
static Int_t init()
static const char * as_STRING(UInt_t idx)
RooRealVar & asVAR(const char *)
CINT constructor interface, return constructor string argument #idx as RooRealVar reference found in ...
Int_t asINT(const char *)
CINT constructor interface, return constructor string argument #idx as Int_t.
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:62
Int_t getSize() const
RooAbsReal * createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none()) const
Create an object that represents the integral of the function over one or more observables listed in ...
Definition: RooAbsReal.cxx:503
Class RooNLLVar implements a a -log(likelihood) calculation from a dataset and a PDF.
Definition: RooNLLVar.h:26
RooAbsReal & asFUNC(const char *)
CINT constructor interface, return constructor string argument #idx as RooAbsReal reference found in ...
std::stack< std::string > _autoNamePrefix
Bool_t defineSet(const char *name, const RooArgSet &aset, Bool_t importMissing=kFALSE)
Define a named RooArgSet with given constituents.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:488
unsigned int UInt_t
Definition: RtypesCore.h:42
void SetName(const char *name)
Set the name of the TNamed.
Definition: RooAbsArg.cxx:2390
char * Form(const char *fmt,...)
static RooDataHist & as_DHIST(UInt_t idx)
TLine * l
Definition: textangle.C:4
RooArgSet asSET(const char *)
CINT constructor interface, return constructor string argument #idx as RooArgSet of objects found in ...
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:37
float xmax
Definition: THbookFile.cxx:93
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4610
std::string processCreateArg(std::string &func, std::vector< std::string > &args)
Glue function between high-level syntax and low-level factory call to createArg: Process a parsed cal...
RooDataHist & asDHIST(const char *)
CINT constructor interface, return constructor string argument #idx as RooDataHist object found in wo...
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:29
RooCategory represents a fundamental (non-derived) discrete value object.
Definition: RooCategory.h:25
static Int_t as_INT(UInt_t idx)
RooProduct a RooAbsReal implementation that represent the product of a given set of other RooAbsReal ...
Definition: RooProduct.h:32
TObject * obj(const char *name) const
Return any type of object (RooAbsArg, RooAbsData or generic object) with given name) ...
RooProdPdf * prod(const char *objName, const char *pdfList)
RooFactoryWSTool(RooWorkspace &ws)
static RooFactoryWSTool * of()
RooAbsRealLValue & asVARLV(const char *)
CINT constructor interface, return constructor string argument #idx as RooAbsRealLValue reference fou...
RooAbsData & asDATA(const char *)
CINT constructor interface, return constructor string argument #idx as RooAbsData object found in wor...
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:35
Double_t asDOUBLE(const char *)
CINT constructor interface, return constructor string argument #idx as Double_t.
void Delete(Option_t *o=0)
Remove all elements in collection and delete all elements NB: Collection does not own elements...
#define ClassImp(name)
Definition: Rtypes.h:279
RooAbsPdf * pdf(const char *name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
double Double_t
Definition: RtypesCore.h:55
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
RooAddition * addfunc(const char *objName, const char *specList)
std::vector< std::string > ctorArgs(const char *className)
double func(double *x, double *p)
Definition: stressTF1.cxx:213
static RooAbsCategory & as_CATFUNC(UInt_t idx)
RooDataSet & asDSET(const char *)
CINT constructor interface, return constructor string argument #idx as RooDataSet object found in wor...
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2893
RooRealVar * var(const char *name) const
Retrieve real-valued variable (RooRealVar) with given name. A null pointer is returned if not found...
TClass * resolveClassName(const char *className)
static std::map< std::string, IFace * > * _hooks
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:65
Mother of all ROOT objects.
Definition: TObject.h:37
std::string create(RooFactoryWSTool &ft, const char *typeName, const char *instanceName, std::vector< std::string > args)
Concatenate list of args into comma separated string.
void clearError()
Associated workspace.
Bool_t commitTransaction()
typedef void((*Func_t)())
RooConstVar & RooConst(Double_t val)
Ta Range(0, 0, 1, 1)
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
Bool_t import(const RooAbsArg &arg, const RooCmdArg &arg1=RooCmdArg(), const RooCmdArg &arg2=RooCmdArg(), const RooCmdArg &arg3=RooCmdArg(), const RooCmdArg &arg4=RooCmdArg(), const RooCmdArg &arg5=RooCmdArg(), const RooCmdArg &arg6=RooCmdArg(), const RooCmdArg &arg7=RooCmdArg(), const RooCmdArg &arg8=RooCmdArg(), const RooCmdArg &arg9=RooCmdArg())
Import a RooAbsArg object, e.g.
RooCategory & asCAT(const char *)
CINT constructor interface, return constructor string argument #idx as RooCategory reference found in...
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
const RooArgSet * set(const char *name)
Return pointer to previously defined named set with given nmame If no such set is found a null pointe...
#define NULL
Definition: Rtypes.h:82
std::string processCompositeExpression(const char *arg)
Process a single composite expression.
std::string processCreateVar(std::string &func, std::vector< std::string > &args)
Glue function between high-level syntax and low-level factory call to createVariable: Process a parse...
Bool_t defineType(const char *label)
Define a state with given name, the lowest available positive integer is assigned as index...
std::string processListExpression(const char *arg)
Process a list of high-level expression.
static void registerSpecial(const char *typeName, RooFactoryWSTool::IFace *iface)
Register foreign special objects in factory.
RooAddition calculates the sum of a set of RooAbsReal terms, or when constructed with two sets...
Definition: RooAddition.h:26
RooDerivative * derivative(RooRealVar &obs, Int_t order=1, Double_t eps=0.001)
Return function representing first, second or third order derivative of this function.
Definition: first.py:1
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
RooCategory * createCategory(const char *name, const char *stateNameList=0)
Low-level factory interface for creating a RooCategory with a given list of state names...
const Bool_t kTRUE
Definition: Rtypes.h:91
std::string processMetaArg(std::string &func, std::vector< std::string > &args)
Concatenate list of args into comma separated string.
RooWorkspace * _ws
RooAbsArg * createArg(const char *className, const char *objName, const char *varList)
Low-level factory interface for creating a RooAbsPdf of a given class with a given list of input vari...
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset...
RooAbsPdf & asPDF(const char *)
CINT constructor interface, return constructor string argument #idx as RooAbsPdf reference found in w...
Bool_t checkSyntax(const char *arg)
Perform basic syntax on given factory expression.
static TObject & as_OBJ(UInt_t idx)
static RooCategory & as_CAT(UInt_t idx)
char name[80]
Definition: TGX11.cxx:109
static Int_t dummy
static RooAbsArg & as_ARG(UInt_t idx)
static RooAbsReal & as_FUNC(UInt_t idx)
The RooWorkspace is a persistable container for RooFit projects.
Definition: RooWorkspace.h:42
virtual std::string create(RooFactoryWSTool &ft, const char *typeName, const char *instanceName, std::vector< std::string > args)=0
virtual ~RooFactoryWSTool()
Destructor.