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