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