Logo ROOT   6.18/05
Reference Guide
RooClassFactory.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 RooClassFactory.cxx
19\class RooClassFactory
20\ingroup Roofitcore
21
22RooClassFactory is a clase like 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 immediate
26instantiate objects.
27**/
28
29#include "RooFit.h"
30#include "TClass.h"
31#include "RooClassFactory.h"
32#include "RooErrorHandler.h"
33#include "RooAbsReal.h"
34#include "RooAbsCategory.h"
35#include "RooArgList.h"
36#include "RooMsgService.h"
37#include "TInterpreter.h"
38#include "RooWorkspace.h"
39#include "RooGlobalFunc.h"
40#include "RooAbsPdf.h"
41#include <fstream>
42
43using namespace std ;
44
46;
47
48static Int_t init();
49
50static Int_t dummy = init() ;
51
52static Int_t init()
53{
57 (void)dummy;
58 return 0 ;
59}
60
61
62
63
64////////////////////////////////////////////////////////////////////////////////
65/// Default constructor
66
68{
69}
70
71
72
73////////////////////////////////////////////////////////////////////////////////
74/// Destructor
75
77{
78}
79
80
81
82////////////////////////////////////////////////////////////////////////////////
83
84Bool_t RooClassFactory::makeAndCompilePdf(const char* name, const char* expression, const RooArgList& vars, const char* intExpression)
85{
86 string realArgNames,catArgNames ;
87 TIterator* iter = vars.createIterator() ;
88 RooAbsArg* arg ;
89 while((arg=(RooAbsArg*)iter->Next())) {
90 if (dynamic_cast<RooAbsReal*>(arg)) {
91 if (realArgNames.size()>0) realArgNames += "," ;
92 realArgNames += arg->GetName() ;
93 } else if (dynamic_cast<RooAbsCategory*>(arg)) {
94 if (catArgNames.size()>0) catArgNames += "," ;
95 catArgNames += arg->GetName() ;
96 } else {
97 oocoutE((RooAbsArg*)0,InputArguments) << "RooClassFactory::makeAndCompilePdf ERROR input argument " << arg->GetName()
98 << " is neither RooAbsReal nor RooAbsCategory and is ignored" << endl ;
99 }
100 }
101 delete iter ;
102
103 Bool_t ret = makePdf(name,realArgNames.c_str(),catArgNames.c_str(),expression,intExpression?kTRUE:kFALSE,kFALSE,intExpression) ;
104 if (ret) {
105 return ret ;
106 }
107
108 if (gInterpreter->GetRootMapFiles()==0) {
109 gInterpreter->EnableAutoLoading() ;
110 }
111
113 gInterpreter->ProcessLineSynch(Form(".L %s.cxx+",name),&ecode) ;
114 return (ecode!=TInterpreter::kNoError) ;
115}
116
117
118
119////////////////////////////////////////////////////////////////////////////////
120/// Write, compile and load code for a RooAbsReal implementation with
121/// class name 'name', taking all elements of 'vars' as constructor
122/// arguments. The initial value expression is taken to be
123/// 'expression' which can be any one-line C++ expression in terms of
124/// variables that occur in 'vars'. You can add optional expressions
125/// for analytical integrals to be advertised by your class in the
126/// syntax
127/// "<intObsName>:<CPPAnaIntExpression>;<intObsName,intObsName>:<CPPAnaIntExpression>"
128/// where <intObsName> a name of the observable integrated over and
129/// <CPPAnaIntExpression> is the C++ expression that calculates that
130/// integral.
131
132Bool_t RooClassFactory::makeAndCompileFunction(const char* name, const char* expression, const RooArgList& vars, const char* intExpression)
133{
134 string realArgNames,catArgNames ;
135 TIterator* iter = vars.createIterator() ;
136 RooAbsArg* arg ;
137 while((arg=(RooAbsArg*)iter->Next())) {
138 if (dynamic_cast<RooAbsReal*>(arg)) {
139 if (realArgNames.size()>0) realArgNames += "," ;
140 realArgNames += arg->GetName() ;
141 } else if (dynamic_cast<RooAbsCategory*>(arg)) {
142 if (catArgNames.size()>0) catArgNames += "," ;
143 catArgNames += arg->GetName() ;
144 } else {
145 oocoutE((RooAbsArg*)0,InputArguments) << "RooClassFactory::makeAndCompileFunction ERROR input argument " << arg->GetName()
146 << " is neither RooAbsReal nor RooAbsCategory and is ignored" << endl ;
147 }
148 }
149 delete iter ;
150
151 Bool_t ret = makeFunction(name,realArgNames.c_str(),catArgNames.c_str(),expression,intExpression?kTRUE:kFALSE,intExpression) ;
152 if (ret) {
153 return ret ;
154 }
155
156 if (gInterpreter->GetRootMapFiles()==0) {
157 gInterpreter->EnableAutoLoading() ;
158 }
159
161 gInterpreter->ProcessLineSynch(Form(".L %s.cxx+",name),&ecode) ;
162 return (ecode!=TInterpreter::kNoError) ;
163}
164
165
166////////////////////////////////////////////////////////////////////////////////
167/// Write, compile and load code and instantiate object for a
168/// RooAbsReal implementation with class name 'name', taking all
169/// elements of 'vars' as constructor arguments. The initial value
170/// expression is taken to be 'expression' which can be any one-line
171/// C++ expression in terms of variables that occur in 'vars'.
172///
173/// The returned object is an instance of the object you just defined
174/// connected to the variables listed in 'vars'. The name of the
175/// object is 'name', its class name Roo<name>Class.
176///
177/// This function is an effective compiled replacement of RooFormulaVar
178///
179/// You can add optional expressions for analytical integrals to be
180/// advertised by your class in the syntax
181/// "<intObsName>:<CPPAnaIntExpression>;<intObsName,intObsName>:<CPPAnaIntExpression>"
182/// where <intObsName> a name of the observable integrated over and
183/// <CPPAnaIntExpression> is the C++ expression that calculates that
184/// integral.
185
186RooAbsReal* RooClassFactory::makeFunctionInstance(const char* name, const char* expression, const RooArgList& vars, const char* intExpression)
187{
188 // Construct unique class name for this function expression
189 string tmpName(name) ;
190 tmpName[0] = toupper(tmpName[0]) ;
191 string className = Form("Roo%sFunc",tmpName.c_str()) ;
192
193 return makeFunctionInstance(className.c_str(),name,expression,vars,intExpression) ;
194}
195
196////////////////////////////////////////////////////////////////////////////////
197/// Write, compile and load code and instantiate object for a
198/// RooAbsReal implementation with class name 'name', taking all
199/// elements of 'vars' as constructor arguments. The initial value
200/// expression is taken to be 'expression' which can be any one-line
201/// C++ expression in terms of variables that occur in 'vars'.
202///
203/// The returned object is an instance of the object you just defined
204/// connected to the variables listed in 'vars'. The name of the
205/// object is 'name', its class name Roo<name>Class.
206///
207/// This function is an effective compiled replacement of RooFormulaVar
208///
209/// You can add optional expressions for analytical integrals to be
210/// advertised by your class in the syntax
211/// "<intObsName>:<CPPAnaIntExpression>;<intObsName,intObsName>:<CPPAnaIntExpression>"
212/// where <intObsName> a name of the observable integrated over and
213/// <CPPAnaIntExpression> is the C++ expression that calculates that
214/// integral.
215
216RooAbsReal* RooClassFactory::makeFunctionInstance(const char* className, const char* name, const char* expression, const RooArgList& vars, const char* intExpression)
217{
218 if (gInterpreter->GetRootMapFiles()==0) {
219 gInterpreter->EnableAutoLoading() ;
220 }
221
222 // Use class factory to compile and link specialized function
223 Bool_t error = makeAndCompileFunction(className,expression,vars,intExpression) ;
224
225 // Check that class was created OK
226 if (error) {
228 }
229
230 // Create CINT line that instantiates specialized object
231 string line = Form("new %s(\"%s\",\"%s\"",className,name,name) ;
232
233 // Make list of pointer values (represented in hex ascii) to be passed to cint
234 // Note that the order of passing arguments must match the convention in which
235 // the class code is generated: first all reals, then all categories
236
237 TIterator* iter = vars.createIterator() ;
238 string argList ;
239 // First pass the RooAbsReal arguments in the list order
240 RooAbsArg* var ;
241 while((var=(RooAbsArg*)iter->Next())) {
242 if (dynamic_cast<RooAbsReal*>(var)) {
243 argList += Form(",*((RooAbsReal*)0x%lx)",(ULong_t)var) ;
244 }
245 }
246 iter->Reset() ;
247 // Next pass the RooAbsCategory arguments in the list order
248 while((var=(RooAbsArg*)iter->Next())) {
249 if (dynamic_cast<RooAbsCategory*>(var)) {
250 argList += Form(",*((RooAbsCategory*)0x%lx)",(ULong_t)var) ;
251 }
252 }
253 delete iter ;
254
255 line += argList + ") ;" ;
256
257 // Let CINT instantiate specialized formula
258 return (RooAbsReal*) gInterpreter->ProcessLineSynch(line.c_str()) ;
259}
260
261
262
263
264////////////////////////////////////////////////////////////////////////////////
265/// Write, compile and load code and instantiate object for a
266/// RooAbsPdf implementation with class name 'name', taking all
267/// elements of 'vars' as constructor arguments. The initial value
268/// expression is taken to be 'expression' which can be any one-line
269/// C++ expression in terms of variables that occur in 'vars'.
270///
271/// The returned object is an instance of the object you just defined
272/// connected to the variables listed in 'vars'. The name of the
273/// object is 'name', its class name Roo<name>Class.
274///
275/// This function is an effective compiled replacement of RooGenericPdf
276///
277/// You can add optional expressions for analytical integrals to be
278/// advertised by your class in the syntax
279/// "<intObsName>:<CPPAnaIntExpression>;<intObsName,intObsName>:<CPPAnaIntExpression>"
280/// where <intObsName> a name of the observable integrated over and
281/// <CPPAnaIntExpression> is the C++ expression that calculates that
282/// integral.
283
284RooAbsPdf* RooClassFactory::makePdfInstance(const char* name, const char* expression,
285 const RooArgList& vars, const char* intExpression)
286{
287 // Construct unique class name for this function expression
288 string tmpName(name) ;
289 tmpName[0] = toupper(tmpName[0]) ;
290 string className = Form("Roo%sPdf",tmpName.c_str()) ;
291
292 return makePdfInstance(className.c_str(),name,expression,vars,intExpression) ;
293}
294
295////////////////////////////////////////////////////////////////////////////////
296/// Write, compile and load code and instantiate object for a
297/// RooAbsPdf implementation with class name 'name', taking all
298/// elements of 'vars' as constructor arguments. The initial value
299/// expression is taken to be 'expression' which can be any one-line
300/// C++ expression in terms of variables that occur in 'vars'.
301///
302/// The returned object is an instance of the object you just defined
303/// connected to the variables listed in 'vars'. The name of the
304/// object is 'name', its class name Roo<name>Class.
305///
306/// This function is an effective compiled replacement of RooGenericPdf
307///
308/// You can add optional expressions for analytical integrals to be
309/// advertised by your class in the syntax
310/// "<intObsName>:<CPPAnaIntExpression>;<intObsName,intObsName>:<CPPAnaIntExpression>"
311/// where <intObsName> a name of the observable integrated over and
312/// <CPPAnaIntExpression> is the C++ expression that calculates that
313/// integral.
314
315RooAbsPdf* RooClassFactory::makePdfInstance(const char* className, const char* name, const char* expression,
316 const RooArgList& vars, const char* intExpression)
317{
318 if (gInterpreter->GetRootMapFiles()==0) {
319 gInterpreter->EnableAutoLoading() ;
320 }
321
322 // Use class factory to compile and link specialized function
323 Bool_t error = makeAndCompilePdf(className,expression,vars,intExpression) ;
324
325 // Check that class was created OK
326 if (error) {
328 }
329
330 // Create CINT line that instantiates specialized object
331 string line = Form("new %s(\"%s\",\"%s\"",className,name,name) ;
332
333 // Make list of pointer values (represented in hex ascii) to be passed to cint
334 // Note that the order of passing arguments must match the convention in which
335 // the class code is generated: first all reals, then all categories
336
337 TIterator* iter = vars.createIterator() ;
338 string argList ;
339 // First pass the RooAbsReal arguments in the list order
340 RooAbsArg* var ;
341 while((var=(RooAbsArg*)iter->Next())) {
342 if (dynamic_cast<RooAbsReal*>(var)) {
343 argList += Form(",*((RooAbsReal*)0x%lx)",(ULong_t)var) ;
344 }
345 }
346 iter->Reset() ;
347 // Next pass the RooAbsCategory arguments in the list order
348 while((var=(RooAbsArg*)iter->Next())) {
349 if (dynamic_cast<RooAbsCategory*>(var)) {
350 argList += Form(",*((RooAbsCategory*)0x%lx)",(ULong_t)var) ;
351 }
352 }
353 delete iter ;
354
355 line += argList + ") ;" ;
356
357 // Let CINT instantiate specialized formula
358 return (RooAbsPdf*) gInterpreter->ProcessLineSynch(line.c_str()) ;
359}
360
361
362
363////////////////////////////////////////////////////////////////////////////////
364/// Write code for a RooAbsPdf implementation with class name 'name',
365/// taking RooAbsReal arguments with names listed in argNames and
366/// RooAbsCategory arguments with names listed in catArgNames as
367/// constructor arguments (use a comma separated list for multiple
368/// arguments). The initial value expression is taken to be
369/// 'expression' which can be any one-line C++ expression in terms of
370/// variables that occur in 'vars'. Skeleton code for handling of
371/// analytical integrals is added if hasAnaInt is true. You can add
372/// optional expressions for analytical integrals to be advertised by
373/// your class in the syntax
374/// "<intObsName>:<CPPAnaIntExpression>;<intObsName,intObsName>:<CPPAnaIntExpression>"
375/// where <intObsName> a name of the observable integrated over and
376/// <CPPAnaIntExpression> is the C++ expression that calculates that
377/// integral. Skeleton code for internal event generation is added
378/// if hasIntGen is true
379///
380
381Bool_t RooClassFactory::makePdf(const char* name, const char* argNames, const char* catArgNames, const char* expression,
382 Bool_t hasAnaInt, Bool_t hasIntGen, const char* intExpression)
383{
384 return makeClass("RooAbsPdf",name,argNames,catArgNames,expression,hasAnaInt,hasIntGen,intExpression) ;
385}
386
387
388////////////////////////////////////////////////////////////////////////////////
389/// Write code for a RooAbsReal implementation with class name 'name',
390/// taking RooAbsReal arguments with names listed in argNames and
391/// RooAbsCategory arguments with names listed in catArgNames as
392/// constructor arguments (use a comma separated list for multiple
393/// arguments). The initial value expression is taken to be
394/// 'expression' which can be any one-line C++ expression in terms of
395/// variables that occur in 'vars'. Skeleton code for handling of
396/// analytical integrals is added if hasAnaInt is true. You can add
397/// optional expressions for analytical integrals to be advertised by
398/// your class in the syntax
399/// "<intObsName>:<CPPAnaIntExpression>;<intObsName,intObsName>:<CPPAnaIntExpression>"
400/// where <intObsName> a name of the observable integrated over and
401/// <CPPAnaIntExpression> is the C++ expression that calculates that
402/// integral.
403
404Bool_t RooClassFactory::makeFunction(const char* name, const char* argNames, const char* catArgNames, const char* expression, Bool_t hasAnaInt, const char* intExpression)
405{
406 return makeClass("RooAbsReal",name,argNames,catArgNames,expression,hasAnaInt,kFALSE,intExpression) ;
407}
408
409
410////////////////////////////////////////////////////////////////////////////////
411/// Write code for a 'baseName' implementation with class name 'className',
412/// taking RooAbsReal arguments with names listed in argNames and
413/// RooAbsCategory arguments with names listed in catArgNames as
414/// constructor arguments (use a comma separated list for multiple
415/// arguments). The initial value expression is taken to be
416/// 'expression' which can be any one-line C++ expression in terms of
417/// variables that occur in 'vars'. Skeleton code for handling of
418/// analytical integrals is added if hasAnaInt is true. You can add
419/// optional expressions for analytical integrals to be advertised by
420/// your class in the syntax
421/// "<intObsName>:<CPPAnaIntExpression>;<intObsName,intObsName>:<CPPAnaIntExpression>"
422/// where <intObsName> a name of the observable integrated over and
423/// <CPPAnaIntExpression> is the C++ expression that calculates that
424/// integral. Skeleton code for internal event generation is added
425/// if hasIntGen is true
426///
427
428Bool_t RooClassFactory::makeClass(const char* baseName, const char* className, const char* realArgNames, const char* catArgNames,
429 const char* expression, Bool_t hasAnaInt, Bool_t hasIntGen, const char* intExpression)
430{
431 // Check that arguments were given
432 if (!baseName) {
433 oocoutE((TObject*)0,InputArguments) << "RooClassFactory::makeClass: ERROR: a base class name must be given" << endl ;
434 return kTRUE ;
435 }
436
437 if (!className) {
438 oocoutE((TObject*)0,InputArguments) << "RooClassFactory::makeClass: ERROR: a class name must be given" << endl ;
439 return kTRUE ;
440 }
441
442 if ((!realArgNames || !*realArgNames) && (!catArgNames || !*catArgNames)) {
443 oocoutE((TObject*)0,InputArguments) << "RooClassFactory::makeClass: ERROR: A list of input argument names must be given" << endl ;
444 return kTRUE ;
445 }
446
447 if (intExpression && !hasAnaInt) {
448 oocoutE((TObject*)0,InputArguments) << "RooClassFactory::makeClass: ERROR no analytical integration code requestion, but expression for analytical integral provided" << endl ;
449 return kTRUE ;
450 }
451
452 // Parse comma separated list of argument names into list of strings
453 vector<string> alist ;
454 vector<bool> isCat ;
455
456 if (realArgNames && *realArgNames) {
457 const size_t bufSize = strlen(realArgNames)+1;
458 char* buf = new char[bufSize] ;
459 strlcpy(buf,realArgNames,bufSize) ;
460 char* token = strtok(buf,",") ;
461 while(token) {
462 alist.push_back(token) ;
463 isCat.push_back(false) ;
464 token = strtok(0,",") ;
465 }
466 delete[] buf ;
467 }
468 if (catArgNames && *catArgNames) {
469 const size_t bufSize = strlen(catArgNames)+1;
470 char* buf = new char[bufSize] ;
471 strlcpy(buf,catArgNames,bufSize) ;
472 char* token = strtok(buf,",") ;
473 while(token) {
474 alist.push_back(token) ;
475 isCat.push_back(true) ;
476 token = strtok(0,",") ;
477 }
478 delete[] buf ;
479 }
480
481 TString impFileName(className), hdrFileName(className) ;
482 impFileName += ".cxx" ;
483 hdrFileName += ".h" ;
484
485 TString ifdefName(className) ;
486 ifdefName.ToUpper() ;
487
488 ofstream hf(hdrFileName) ;
489 hf << "/*****************************************************************************" << endl
490 << " * Project: RooFit *" << endl
491 << " * *" << endl
492 << " * This code was autogenerated by RooClassFactory * " << endl
493 << " *****************************************************************************/" << endl
494 << endl
495 << "#ifndef " << ifdefName << endl
496 << "#define " << ifdefName << endl
497 << "" << endl
498 << "#include \"" << baseName << ".h\"" << endl
499 << "#include \"RooRealProxy.h\"" << endl
500 << "#include \"RooCategoryProxy.h\"" << endl
501 << "#include \"RooAbsReal.h\"" << endl
502 << "#include \"RooAbsCategory.h\"" << endl
503 << " " << endl
504 << "class " << className << " : public " << baseName << " {" << endl
505 << "public:" << endl
506 << " " << className << "() {} ; " << endl
507 << " " << className << "(const char *name, const char *title," << endl ;
508
509 // Insert list of input arguments
510 unsigned int i ;
511 for (i=0 ; i<alist.size() ; i++) {
512 if (!isCat[i]) {
513 hf << " RooAbsReal& _" ;
514 } else {
515 hf << " RooAbsCategory& _" ;
516 }
517 hf << alist[i] ;
518 if (i==alist.size()-1) {
519 hf << ");" << endl ;
520 } else {
521 hf << "," << endl ;
522 }
523 }
524
525 hf << " " << className << "(const " << className << "& other, const char* name=0) ;" << endl
526 << " virtual TObject* clone(const char* newname) const { return new " << className << "(*this,newname); }" << endl
527 << " inline virtual ~" << className << "() { }" << endl
528 << endl ;
529
530 if (hasAnaInt) {
531 hf << " Int_t getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* rangeName=0) const ;" << endl
532 << " Double_t analyticalIntegral(Int_t code, const char* rangeName=0) const ;" << endl
533 << "" << endl ;
534 }
535
536 if (hasIntGen) {
537 hf << " Int_t getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, Bool_t staticInitOK=kTRUE) const;" << endl
538 << " void initGenerator(Int_t code) {} ; // optional pre-generation initialization" << endl
539 << " void generateEvent(Int_t code);" << endl
540 << endl ;
541 }
542
543 hf << "protected:" << endl
544 << "" << endl ;
545
546 // Insert list of input arguments
547 for (i=0 ; i<alist.size() ; i++) {
548 if (!isCat[i]) {
549 hf << " RooRealProxy " << alist[i] << " ;" << endl ;
550 } else {
551 hf << " RooCategoryProxy " << alist[i] << " ;" << endl ;
552 }
553 }
554
555 hf << " " << endl
556 << " Double_t evaluate() const ;" << endl
557 << "" << endl
558 << "private:" << endl
559 << "" << endl
560 << " ClassDef(" << className << ",1) // Your description goes here..." << endl
561 << "};" << endl
562 << " " << endl
563 << "#endif" << endl ;
564
565
566 ofstream cf(impFileName) ;
567
568 cf << "/***************************************************************************** " << endl
569 << " * Project: RooFit * " << endl
570 << " * * " << endl
571 << " * This code was autogenerated by RooClassFactory * " << endl
572 << " *****************************************************************************/ " << endl
573 << endl
574 << "// Your description goes here... " << endl
575 << endl
576
577 << "#include \"Riostream.h\" " << endl
578 << endl
579
580 << "#include \"" << className << ".h\" " << endl
581 << "#include \"RooAbsReal.h\" " << endl
582 << "#include \"RooAbsCategory.h\" " << endl
583 << "#include <math.h> " << endl
584 << "#include \"TMath.h\" " << endl
585 << endl
586
587 << "ClassImp(" << className << "); " << endl
588 << endl
589
590 << " " << className << "::" << className << "(const char *name, const char *title, " << endl ;
591
592 // Insert list of proxy constructors
593 for (i=0 ; i<alist.size() ; i++) {
594 if (!isCat[i]) {
595 cf << " RooAbsReal& _" << alist[i] ;
596 } else {
597 cf << " RooAbsCategory& _" << alist[i] ;
598 }
599 if (i<alist.size()-1) {
600 cf << "," ;
601 } else {
602 cf << ") :" ;
603 }
604 cf << endl ;
605 }
606
607 // Insert base class constructor
608 cf << " " << baseName << "(name,title), " << endl ;
609
610 // Insert list of proxy constructors
611 for (i=0 ; i<alist.size() ; i++) {
612 cf << " " << alist[i] << "(\"" << alist[i] << "\",\"" << alist[i] << "\",this,_" << alist[i] << ")" ;
613 if (i<alist.size()-1) {
614 cf << "," ;
615 }
616 cf << endl ;
617 }
618
619 cf << " { " << endl
620 << " } " << endl
621 << endl
622 << endl
623
624 << " " << className << "::" << className << "(const " << className << "& other, const char* name) : " << endl
625 << " " << baseName << "(other,name), " << endl ;
626
627 for (i=0 ; i<alist.size() ; i++) {
628 cf << " " << alist[i] << "(\"" << alist[i] << "\",this,other." << alist[i] << ")" ;
629 if (i<alist.size()-1) {
630 cf << "," ;
631 }
632 cf << endl ;
633 }
634
635 cf << " { " << endl
636 << " } " << endl
637 << endl
638 << endl
639 << endl
640
641 << " Double_t " << className << "::evaluate() const " << endl
642 << " { " << endl
643 << " // ENTER EXPRESSION IN TERMS OF VARIABLE ARGUMENTS HERE " << endl
644 << " return " << expression << " ; " << endl
645 << " } " << endl
646 << endl
647 << endl
648 << endl ;
649
650 if (hasAnaInt) {
651
652 vector<string> intObs ;
653 vector<string> intExpr ;
654 // Parse analytical integration expression if provided
655 // Expected form is observable:expression,observable,observable:expression;[...]
656 if (intExpression && *intExpression) {
657 const size_t bufSize = strlen(intExpression)+1;
658 char* buf = new char[bufSize] ;
659 strlcpy(buf,intExpression,bufSize) ;
660 char* ptr = strtok(buf,":") ;
661 while(ptr) {
662 intObs.push_back(ptr) ;
663 intExpr.push_back(strtok(0,";")) ;
664 ptr = strtok(0,":") ;
665 }
666 delete[] buf ;
667 }
668
669 cf << " Int_t " << className << "::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /*rangeName*/) const " << endl
670 << " { " << endl
671 << " // LIST HERE OVER WHICH VARIABLES ANALYTICAL INTEGRATION IS SUPPORTED, " << endl
672 << " // ASSIGN A NUMERIC CODE FOR EACH SUPPORTED (SET OF) PARAMETERS " << endl
673 << " // THE EXAMPLE BELOW ASSIGNS CODE 1 TO INTEGRATION OVER VARIABLE X" << endl
674 << " // YOU CAN ALSO IMPLEMENT MORE THAN ONE ANALYTICAL INTEGRAL BY REPEATING THE matchArgs " << endl
675 << " // EXPRESSION MULTIPLE TIMES" << endl
676 << endl ;
677
678 if (intObs.size()>0) {
679 for (UInt_t ii=0 ; ii<intObs.size() ; ii++) {
680 cf << " if (matchArgs(allVars,analVars," << intObs[ii] << ")) return " << ii+1 << " ; " << endl ;
681 }
682 } else {
683 cf << " // if (matchArgs(allVars,analVars,x)) return 1 ; " << endl ;
684 }
685
686 cf << " return 0 ; " << endl
687 << " } " << endl
688 << endl
689 << endl
690 << endl
691
692 << " Double_t " << className << "::analyticalIntegral(Int_t code, const char* rangeName) const " << endl
693 << " { " << endl
694 << " // RETURN ANALYTICAL INTEGRAL DEFINED BY RETURN CODE ASSIGNED BY getAnalyticalIntegral" << endl
695 << " // THE MEMBER FUNCTION x.min(rangeName) AND x.max(rangeName) WILL RETURN THE INTEGRATION" << endl
696 << " // BOUNDARIES FOR EACH OBSERVABLE x" << endl
697 << endl ;
698
699 if (intObs.size()>0) {
700 for (UInt_t ii=0 ; ii<intObs.size() ; ii++) {
701 cf << " if (code==" << ii+1 << ") { return (" << intExpr[ii] << ") ; } " << endl ;
702 }
703 } else {
704 cf << " // assert(code==1) ; " << endl
705 << " // return (x.max(rangeName)-x.min(rangeName)) ; " << endl ;
706 }
707
708 cf << " return 0 ; " << endl
709 << " } " << endl
710 << endl
711 << endl
712 << endl ;
713 }
714
715 if (hasIntGen) {
716 cf << " Int_t " << className << "::getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, Bool_t /*staticInitOK*/) const " << endl
717 << " { " << endl
718 << " // LIST HERE OVER WHICH VARIABLES INTERNAL GENERATION IS SUPPORTED, " << endl
719 << " // ASSIGN A NUMERIC CODE FOR EACH SUPPORTED (SET OF) PARAMETERS " << endl
720 << " // THE EXAMPLE BELOW ASSIGNS CODE 1 TO INTEGRATION OVER VARIABLE X" << endl
721 << " // YOU CAN ALSO IMPLEMENT MORE THAN ONE GENERATOR CONFIGURATION BY REPEATING THE matchArgs " << endl
722 << " // EXPRESSION MULTIPLE TIMES. IF THE FLAG staticInitOK IS TRUE THEN IT IS SAFE TO PRECALCULATE " << endl
723 << " // INTERMEDIATE QUANTITIES IN initGenerator(), IF IT IS NOT SET THEN YOU SHOULD NOT ADVERTISE" << endl
724 << " // ANY GENERATOR METHOD THAT RELIES ON PRECALCULATIONS IN initGenerator()" << endl
725 << endl
726 << " // if (matchArgs(directVars,generateVars,x)) return 1 ; " << endl
727 << " return 0 ; " << endl
728 << " } " << endl
729 << endl
730 << endl
731 << endl
732
733 << " void " << className << "::generateEvent(Int_t code) " << endl
734 << " { " << endl
735 << " // GENERATE SET OF OBSERVABLES DEFINED BY RETURN CODE ASSIGNED BY getGenerator()" << endl
736 << " // RETURN THE GENERATED VALUES BY ASSIGNING THEM TO THE PROXY DATA MEMBERS THAT" << endl
737 << " // REPRESENT THE CHOSEN OBSERVABLES" << endl
738 << endl
739 << " // assert(code==1) ; " << endl
740 << " // x = 0 ; " << endl
741 << " return; " << endl
742 << " } " << endl
743 << endl
744 << endl
745 << endl ;
746 }
747
748
749 return kFALSE ;
750}
751
752////////////////////////////////////////////////////////////////////////////////
753
754std::string RooClassFactory::ClassFacIFace::create(RooFactoryWSTool& ft, const char* typeName, const char* instanceName, std::vector<std::string> args)
755{
756 static int classCounter = 0 ;
757
758 string tn(typeName) ;
759 if (tn=="CEXPR" || tn=="cexpr") {
760
761 if (args.size()<2) {
762 throw string(Form("RooClassFactory::ClassFacIFace::create() ERROR: CEXPR requires at least 2 arguments (expr,var,...), but only %u args found",
763 (UInt_t)args.size())) ;
764 }
765
766 RooAbsArg* ret ;
767 // Strip quotation marks from expression string
768 char expr[1024] ;
769 strncpy(expr,args[0].c_str()+1,args[0].size()-2) ;
770 expr[args[0].size()-2]=0 ;
771
772
773 RooArgList varList ;
774
775 try {
776 if (args.size()==2) {
777 // Interpret 2nd arg as list
778 varList.add(ft.asLIST(args[1].c_str())) ;
779 } else {
780 for (unsigned int i=1 ; i<args.size() ; i++) {
781 varList.add(ft.asARG(args[i].c_str())) ;
782 }
783 }
784 } catch (const string &err) {
785 throw string(Form("RooClassFactory::ClassFacIFace::create() ERROR: %s",err.c_str())) ;
786 }
787
788 string className ;
789 while(true) {
790 className = Form("RooCFAuto%03d%s%s",classCounter,(tn=="CEXPR")?"Pdf":"Func",ft.autoClassNamePostFix()) ;
791 TClass* tc = TClass::GetClass(className.c_str(),kTRUE,kTRUE) ;
792 classCounter++ ;
793 if (!tc) {
794 break ;
795 }
796 }
797
798 if (tn=="CEXPR") {
799 ret = makePdfInstance(className.c_str(),instanceName,expr,varList) ;
800 } else {
801 ret = makeFunctionInstance(className.c_str(),instanceName,expr,varList) ;
802 }
803 if (!ret) {
804 throw string(Form("RooClassFactory::ClassFacIFace::create() ERROR creating %s %s with RooClassFactory",((tn=="CEXPR")?"pdf":"function"),instanceName)) ;
805 }
806
807 // Import object
808 ft.ws().import(*ret,RooFit::Silence()) ;
809
810 // Import class code as well
811 ft.ws().importClassCode(ret->IsA()) ;
812
813
814 } else {
815
816 throw string(Form("RooClassFactory::ClassFacIFace::create() ERROR: Unknown meta-type %s requested",typeName)) ;
817
818 }
819 return string(instanceName) ;
820}
static Int_t dummy
static Int_t init()
#define oocoutE(o, a)
Definition: RooMsgService.h:47
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
char name[80]
Definition: TGX11.cxx:109
#define gInterpreter
Definition: TInterpreter.h:553
char * Form(const char *fmt,...)
typedef void((*Func_t)())
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:70
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
TIterator * createIterator(Bool_t dir=kIterForward) const R__SUGGEST_ALTERNATIVE("begin()
TIterator-style iteration over contained elements.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:21
std::string create(RooFactoryWSTool &ft, const char *typeName, const char *instanceName, std::vector< std::string > args)
RooClassFactory is a clase like TTree::MakeClass() that generates skeleton code for RooAbsPdf and Roo...
static Bool_t makeAndCompileFunction(const char *name, const char *expression, const RooArgList &args, const char *intExpression=0)
Write, compile and load code for a RooAbsReal implementation with class name 'name',...
static RooAbsReal * makeFunctionInstance(const char *className, const char *name, const char *expression, const RooArgList &vars, const char *intExpression=0)
Write, compile and load code and instantiate object for a RooAbsReal implementation with class name '...
static RooAbsPdf * makePdfInstance(const char *className, const char *name, const char *expression, const RooArgList &vars, const char *intExpression=0)
Write, compile and load code and instantiate object for a RooAbsPdf implementation with class name 'n...
static Bool_t makePdf(const char *name, const char *realArgNames=0, const char *catArgNames=0, const char *expression="1.0", Bool_t hasAnaInt=kFALSE, Bool_t hasIntGen=kFALSE, const char *intExpression=0)
Write code for a RooAbsPdf implementation with class name 'name', taking RooAbsReal arguments with na...
RooClassFactory()
Default constructor.
static Bool_t makeClass(const char *className, const char *name, const char *realArgNames=0, const char *catArgNames=0, const char *expression="1.0", Bool_t hasAnaInt=kFALSE, Bool_t hasIntGen=kFALSE, const char *intExpression=0)
Write code for a 'baseName' implementation with class name 'className', taking RooAbsReal arguments w...
static Bool_t makeFunction(const char *name, const char *realArgNames=0, const char *catArgNames=0, const char *expression="1.0", Bool_t hasAnaInt=kFALSE, const char *intExpression=0)
Write code for a RooAbsReal implementation with class name 'name', taking RooAbsReal arguments with n...
virtual ~RooClassFactory()
Destructor.
static Bool_t makeAndCompilePdf(const char *name, const char *expression, const RooArgList &vars, const char *intExpression=0)
static void softAbort()
RooFactoryWSTool is a clase like TTree::MakeClass() that generates skeleton code for RooAbsPdf and Ro...
RooWorkspace & ws()
const char * autoClassNamePostFix() const
RooAbsArg & asARG(const char *)
CINT constructor interface, return constructor string argument #idx as RooAbsArg reference found in w...
static void registerSpecial(const char *typeName, RooFactoryWSTool::IFace *iface)
Register foreign special objects in factory.
RooArgList asLIST(const char *)
CINT constructor interface, return constructor string argument #idx as RooArgList of objects found in...
Bool_t importClassCode(const char *pat="*", Bool_t doReplace=kFALSE)
Inport code of all classes in the workspace that have a class name that matches pattern 'pat' and whi...
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.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
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:2895
Iterator abstract base class.
Definition: TIterator.h:30
virtual void Reset()=0
virtual TObject * Next()=0
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
Basic string class.
Definition: TString.h:131
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1138
TLine * line
@ InputArguments
Definition: RooGlobalFunc.h:58
RooCmdArg Silence(Bool_t flag=kTRUE)