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