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