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