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