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