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