50using std::endl, std::vector, std::string;
73bool makeAndCompileClass(std::string
const &baseClassName, std::string
const &
name, std::string
const &expression,
80 ClassInfo(std::string
const &baseClassName, std::string
const &
name, std::string
const &expression,
106 static std::vector<ClassInfo>
infosVec;
114 if (*found ==
info) {
117 std::stringstream
ss;
118 ss <<
"RooClassFactory ERROR The type, expressions, or variables for the class \"" <<
name
119 <<
"\" are not identical to what you passed last time this class was compiled! This is not allowed.";
120 oocoutE(
nullptr, InputArguments) <<
ss.str() << std::endl;
121 throw std::runtime_error(
ss.str());
136 }
else if (arg->isCategory()) {
141 oocoutE(
nullptr, InputArguments) <<
"RooClassFactory ERROR input argument " << arg->GetName()
142 <<
" is neither RooAbsReal nor RooAbsCategory and is ignored" << endl;
169 std::string
line = std::string(
"new ") + className +
"(\"" +
name +
"\",\"" +
name +
"\"";
179 argList +=
Form(
",*reinterpret_cast<RooAbsReal*>(0x%zx)",
reinterpret_cast<std::size_t
>(var));
184 if (var->isCategory()) {
185 argList +=
Form(
",*reinterpret_cast<RooAbsCategory*>(0x%zx)",
reinterpret_cast<std::size_t
>(var));
189 line += argList +
") ;";
250 string className =
"Roo" +
tmpName +
"Func";
276 std::string
const &expression,
const RooArgList &vars,
295 string className =
"Roo" +
tmpName +
"Pdf";
321 std::string
const &expression,
const RooArgList &vars,
366std::string
listVars(std::vector<std::string>
const &alist, std::vector<bool>
const &
isCat = {})
368 std::stringstream
ss;
369 for (std::size_t i = 0; i < alist.size(); ++i) {
370 if (!
isCat.empty()) {
371 ss << (
isCat[i] ?
"int" :
"double") <<
" ";
374 if (i < alist.size() - 1) {
383 std::stringstream
ss;
384 for (std::size_t i = 0; i < alist.size(); ++i) {
386 <<
"std::span<const double> " << alist[i] <<
"Span = ctx.at(" << alist[i] <<
");\n";
393 std::stringstream
ss;
394 for (std::size_t i = 0; i < alist.size(); ++i) {
395 std::string
name = alist[i] +
"Span";
396 ss <<
name <<
".size() > 1 ? " <<
name <<
"[i] : " <<
name <<
"[0]";
397 if (i < alist.size() - 1) {
407 for (std::string::size_type pos{};
inOut.npos != (pos =
inOut.find(
what.data(), pos,
what.length()));
408 pos +=
with.length()) {
415 return c !=
'_' && !std::isalnum(
c);
418bool isComplex(std::string
const &expression)
422 for (std::size_t i = 0; i < expression.size(); ++i) {
459 oocoutE(
nullptr, InputArguments)
460 <<
"RooClassFactory::makeClass: ERROR: A list of input argument names must be given" << endl;
465 oocoutE(
nullptr, InputArguments) <<
"RooClassFactory::makeClass: ERROR no analytical integration code "
466 "requestion, but expression for analytical integral provided"
476 alist.push_back(
token);
477 isCat.push_back(
false);
480 alist.push_back(
token);
481 isCat.push_back(
true);
485 std::stringstream
hf;
486 hf << R
"(/*****************************************************************************
489 * This code was autogenerated by RooClassFactory *
490 *****************************************************************************/
495#include <BASE_NAME.h>
496#include <RooRealProxy.h>
497#include <RooCategoryProxy.h>
498#include <RooAbsReal.h>
499#include <RooAbsCategory.h>
503class CLASS_NAME : public BASE_NAME {
506 CLASS_NAME(const char *name, const char *title,)";
510 for (i=0 ; i<alist.size() ; i++) {
512 hf <<
" RooAbsReal& _" ;
514 hf <<
" RooAbsCategory& _" ;
517 if (i==alist.size()-1) {
524 hf << R
"( CLASS_NAME(CLASS_NAME const &other, const char *name=nullptr);
525 TObject* clone(const char *newname) const override { return new CLASS_NAME(*this, newname); }
530 int getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char *rangeName=nullptr) const override;
531 double analyticalIntegral(int code, const char *rangeName=nullptr) const override;
537 int getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, bool staticInitOK=true) const override;
538 void initGenerator(int code) override {} // optional pre-generation initialization
539 void generateEvent(int code) override;
543 hf << "protected:" << endl
547 for (i=0 ; i<alist.size() ; i++) {
549 hf <<
" RooRealProxy " << alist[i] <<
" ;" << endl ;
551 hf <<
" RooCategoryProxy " << alist[i] <<
" ;" << endl ;
556 double evaluate() const override;
557 void doEval(RooFit::EvalContext &) const override;
558 void translate(RooFit::Detail::CodeSquashContext &ctx) const override;
562 ClassDefOverride(CLASS_NAME, 1) // Your description goes here...
567 << "inline double CLASS_NAME_evaluate(" <<
listVars(alist,
isCat) <<
") ";
574 // Support also using the imaginary unit
575 using namespace std::complex_literals;
576 // To be able to also comile C code, we define a variable that behaves like the "I" macro from C.
577 constexpr auto I = 1i;
582 // ENTER EXPRESSION IN TERMS OF VARIABLE ARGUMENTS HERE
585 << " return " << expression <<
"; " << endl
589 hf <<
"\n#endif // CLASS_NAME_h";
591 std::stringstream
cf;
593 cf << R
"(/*****************************************************************************
596 * This code was autogenerated by RooClassFactory *
597 *****************************************************************************/
599// Your description goes here...
601#include "CLASS_NAME.h"
603#include <RooAbsReal.h>
604#include <RooAbsCategory.h>
606#include <Riostream.h>
613CLASS_NAME::CLASS_NAME(const char *name, const char *title,
617 for (i=0 ; i<alist.size() ; i++) {
619 cf <<
" RooAbsReal& _" << alist[i] ;
621 cf <<
" RooAbsCategory& _" << alist[i] ;
623 if (i<alist.size()-1) {
632 cf <<
" : BASE_NAME(name,title)," << endl ;
635 for (i=0 ; i<alist.size() ; i++) {
636 cf <<
" " << alist[i] <<
"(\"" << alist[i] <<
"\",\"" << alist[i] <<
"\",this,_" << alist[i] <<
")" ;
637 if (i<alist.size()-1) {
647 <<
"CLASS_NAME::CLASS_NAME(CLASS_NAME const &other, const char *name)" << endl
648 <<
" : BASE_NAME(other,name)," << endl ;
650 for (i=0 ; i<alist.size() ; i++) {
651 cf <<
" " << alist[i] <<
"(\"" << alist[i] <<
"\",this,other." << alist[i] <<
")" ;
652 if (i<alist.size()-1) {
662 <<
"double CLASS_NAME::evaluate() const " << endl
664 <<
" return CLASS_NAME_evaluate(" <<
listVars(alist) <<
"); " << endl
667 <<
"void CLASS_NAME::doEval(RooFit::EvalContext &ctx) const " << endl
671 <<
" std::size_t n = ctx.output().size();\n"
672 <<
" for (std::size_t i = 0; i < n; ++i) {\n"
673 <<
" ctx.output()[i] = CLASS_NAME_evaluate(" <<
getFromVarSpans(alist) <<
");\n"
677cf <<
"void CLASS_NAME::translate(RooFit::Detail::CodeSquashContext &ctx) const\n"
679<<
" ctx.addResult(this, ctx.buildCall(\"CLASS_NAME_evaluate\", " <<
listVars(alist) <<
"));\n"
690 std::vector<char> buf(
bufSize);
692 char* ptr =
strtok(buf.data(),
":") ;
696 ptr =
strtok(
nullptr,
":") ;
701int CLASS_NAME::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char */*rangeName*/) const
703 // Support also using the imaginary unit
704 using namespace std::complex_literals;
705 // To be able to also comile C code, we define a variable that behaves like the "I" macro from C.
706 constexpr auto I = 1i;
708 // LIST HERE OVER WHICH VARIABLES ANALYTICAL INTEGRATION IS SUPPORTED,
709 // ASSIGN A NUMERIC CODE FOR EACH SUPPORTED (SET OF) PARAMETERS. THE EXAMPLE
710 // BELOW ASSIGNS CODE 1 TO INTEGRATION OVER VARIABLE X YOU CAN ALSO
711 // IMPLEMENT MORE THAN ONE ANALYTICAL INTEGRAL BY REPEATING THE matchArgs
712 // EXPRESSION MULTIPLE TIMES.
717 cf <<
" if (matchArgs(allVars,analVars," <<
intObs[
ii] <<
")) return " <<
ii+1 <<
" ; " << endl ;
720 cf <<
" // if (matchArgs(allVars,analVars,x)) return 1 ; " << endl ;
723 cf <<
" return 0 ; " << endl
728 << R
"(double CLASS_NAME::analyticalIntegral(int code, const char *rangeName) const
730 // RETURN ANALYTICAL INTEGRAL DEFINED BY RETURN CODE ASSIGNED BY
731 // getAnalyticalIntegral(). THE MEMBER FUNCTION x.min(rangeName) AND
732 // x.max(rangeName) WILL RETURN THE INTEGRATION BOUNDARIES FOR EACH
738 cf <<
" if (code==" <<
ii+1 <<
") { return (" <<
intExpr[
ii] <<
") ; } " << endl ;
741 cf <<
" // assert(code==1) ; " << endl
742 <<
" // return (x.max(rangeName)-x.min(rangeName)) ; " << endl ;
745 cf <<
" return 0 ; " << endl
751int CLASS_NAME::getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, bool /*staticInitOK*/) const
753 // LIST HERE OVER WHICH VARIABLES INTERNAL GENERATION IS SUPPORTED, ASSIGN A
754 // NUMERIC CODE FOR EACH SUPPORTED (SET OF) PARAMETERS. THE EXAMPLE BELOW
755 // ASSIGNS CODE 1 TO INTEGRATION OVER VARIABLE X. YOU CAN ALSO IMPLEMENT
756 // MORE THAN ONE GENERATOR CONFIGURATION BY REPEATING THE matchArgs
757 // EXPRESSION MULTIPLE TIMES. IF THE FLAG staticInitOK IS TRUE, THEN IT IS
758 // SAFE TO PRECALCULATE INTERMEDIATE QUANTITIES IN initGenerator(), IF IT IS
759 // NOT SET THEN YOU SHOULD NOT ADVERTISE ANY GENERATOR METHOD THAT RELIES ON
760 // PRECALCULATIONS IN initGenerator().
762 // if (matchArgs(directVars,generateVars,x)) return 1;
766void CLASS_NAME::generateEvent(int code)
768 // GENERATE SET OF OBSERVABLES DEFINED BY RETURN CODE ASSIGNED BY
769 // getGenerator(). RETURN THE GENERATED VALUES BY ASSIGNING THEM TO THE
770 // PROXY DATA MEMBERS THAT REPRESENT THE CHOSEN OBSERVABLES.
781 std::ofstream
ohf(className +
".h");
782 std::ofstream
ocf(className +
".cxx");
800 std::vector<std::string> args)
806 if (args.size() < 2) {
807 throw std::runtime_error(
Form(
"RooClassFactory::ClassFacIFace::create() ERROR: CEXPR requires at least 2 "
808 "arguments (expr,var,...), but only %u args found",
816 expr[args[0].size() - 2] = 0;
820 if (args.size() == 2) {
824 for (
unsigned int i = 1; i < args.size(); i++) {
831 className =
Form(
"RooCFAuto%03d%s%s",
classCounter, (
tn ==
"CEXPR") ?
"Pdf" :
"Func",
ft.autoClassNamePostFix());
845 throw std::runtime_error(
846 Form(
"RooClassFactory::ClassFacIFace::create() ERROR creating %s %s with RooClassFactory",
854 ft.ws().importClassCode(
ret->IsA());
virtual RooAbsTestStatistic * create(const char *name, const char *title, RooAbsReal &real, RooAbsData &data, const RooArgSet &projDeps, Configuration const &cfg)=0
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Bool_t operator==(const TDatime &d1, const TDatime &d2)
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
const_iterator begin() const
const_iterator end() const
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Storage_t::size_type size() const
Abstract interface for all probability density functions.
Abstract base class for objects that represent a real value and implements functionality common to al...
RooArgList is a container object that can hold multiple RooAbsArg objects.
static bool makePdf(std::string const &name, std::string const &realArgNames="", std::string const &catArgNames="", std::string const &expression="1.0", bool hasAnaInt=false, bool hasIntGen=false, std::string const &intExpression="")
Write code for a RooAbsPdf implementation with class name 'name'.
static bool makeAndCompilePdf(std::string const &name, std::string const &expression, const RooArgList &vars, std::string const &intExpression="")
static RooAbsReal * makeFunctionInstance(std::string const &className, std::string const &name, std::string const &expression, const RooArgList &vars, std::string const &intExpression="")
Write, compile and load code and instantiate object for a RooAbsReal implementation with class name '...
static bool makeFunction(std::string const &name, std::string const &realArgNames="", std::string const &catArgNames="", std::string const &expression="1.0", bool hasAnaInt=false, std::string const &intExpression="")
Write code for a RooAbsReal implementation with class name 'name', taking RooAbsReal arguments with n...
static RooAbsPdf * makePdfInstance(std::string const &className, std::string const &name, std::string const &expression, const RooArgList &vars, std::string const &intExpression="")
Write, compile and load code and instantiate object for a RooAbsPdf implementation with class name 'n...
static bool makeClass(std::string const &baseName, const std::string &className, std::string const &realArgNames="", std::string const &catArgNames="", std::string const &expression="1.0", bool hasAnaInt=false, bool hasIntGen=false, std::string const &intExpression="")
Write code for a 'baseName' implementation with class name 'className', taking RooAbsReal arguments w...
static bool makeAndCompileFunction(std::string const &name, std::string const &expression, const RooArgList &args, std::string const &intExpression="")
Write, compile and load code for a RooAbsReal implementation with class name 'name',...
static void softAbort()
Soft abort function that interrupts macro execution but doesn't kill ROOT.
TClass instances represent classes, structs and namespaces in the ROOT type system.
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.
RooCmdArg Silence(bool flag=true)
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.