51using std::endl, std::vector, std::string;
 
   74bool makeAndCompileClass(std::string 
const &baseClassName, std::string 
const &
name, std::string 
const &expression,
 
   81      ClassInfo(std::string 
const &baseClassName, std::string 
const &
name, std::string 
const &expression,
 
  107   static std::vector<ClassInfo> 
infosVec;
 
  115      if (*found == 
info) {
 
  118      std::stringstream 
ss;
 
  119      ss << 
"RooClassFactory ERROR The type, expressions, or variables for the class \"" << 
name 
  120         << 
"\" are not identical to what you passed last time this class was compiled! This is not allowed.";
 
  121      oocoutE(
nullptr, InputArguments) << 
ss.str() << std::endl;
 
  122      throw std::runtime_error(
ss.str());
 
  137      } 
else if (arg->isCategory()) {
 
  142         oocoutE(
nullptr, InputArguments) << 
"RooClassFactory ERROR input argument " << arg->GetName()
 
  143                                          << 
" is neither RooAbsReal nor RooAbsCategory and is ignored" << std::endl;
 
  170   std::string 
line = std::string(
"new ") + className + 
"(\"" + 
name + 
"\",\"" + 
name + 
"\"";
 
  180         argList += 
Form(
",*reinterpret_cast<RooAbsReal*>(0x%zx)", 
reinterpret_cast<std::size_t
>(var));
 
  185      if (var->isCategory()) {
 
  186         argList += 
Form(
",*reinterpret_cast<RooAbsCategory*>(0x%zx)", 
reinterpret_cast<std::size_t
>(var));
 
  190   line += argList + 
") ;";
 
  251   string className = 
"Roo" + 
tmpName + 
"Func";
 
 
  277                                                  std::string 
const &expression, 
const RooArgList &vars,
 
 
  296   string className = 
"Roo" + 
tmpName + 
"Pdf";
 
 
  322                                            std::string 
const &expression, 
const RooArgList &vars,
 
 
  367std::string 
listVars(std::vector<std::string> 
const &alist, std::vector<bool> 
const &
isCat = {})
 
  369   std::stringstream 
ss;
 
  370   for (std::size_t i = 0; i < alist.size(); ++i) {
 
  371      if (!
isCat.empty()) {
 
  372         ss << (
isCat[i] ? 
"int" : 
"double") << 
" ";
 
  375      if (i < alist.size() - 1) {
 
  384   std::stringstream 
ss;
 
  385   for (std::size_t i = 0; i < alist.size(); ++i) {
 
  387         << 
"std::span<const double> " << alist[i] << 
"Span = ctx.at(" << alist[i] << 
");\n";
 
  394   std::stringstream 
ss;
 
  395   for (std::size_t i = 0; i < alist.size(); ++i) {
 
  396      std::string 
name = alist[i] + 
"Span";
 
  397      ss << 
name << 
".size() > 1 ? " << 
name << 
"[i] : " << 
name << 
"[0]";
 
  398      if (i < alist.size() - 1) {
 
  407   return c != 
'_' && !std::isalnum(
c);
 
  410bool isComplex(std::string 
const &expression)
 
  414   for (std::size_t i = 0; i < expression.size(); ++i) {
 
  451      oocoutE(
nullptr, InputArguments)
 
  452         << 
"RooClassFactory::makeClass: ERROR: A list of input argument names must be given" << std::endl;
 
  457      oocoutE(
nullptr, InputArguments) << 
"RooClassFactory::makeClass: ERROR no analytical integration code " 
  458                                          "requestion, but expression for analytical integral provided" 
  468      alist.push_back(
token);
 
  469      isCat.push_back(
false);
 
  472      alist.push_back(
token);
 
  473      isCat.push_back(
true);
 
  477  std::stringstream 
hf;
 
  478  hf << R
"(/***************************************************************************** 
  481 * This code was autogenerated by RooClassFactory                            * 
  482 *****************************************************************************/ 
  487#include <BASE_NAME.h> 
  488#include <RooRealProxy.h> 
  489#include <RooCategoryProxy.h> 
  490#include <RooAbsReal.h> 
  491#include <RooAbsCategory.h> 
  495class CLASS_NAME : public BASE_NAME { 
  498   CLASS_NAME(const char *name, const char *title,)"; 
  501  for (std::size_t i=0 ; i<alist.size() ; i++) {
 
  503      hf << 
"        RooAbsReal& _" ;
 
  505      hf << 
"        RooAbsCategory& _" ;
 
  508    if (i==alist.size()-1) {
 
  509      hf << 
");" << std::endl ;
 
  511      hf << 
"," << std::endl ;
 
  515  hf << R
"(  CLASS_NAME(CLASS_NAME const &other, const char *name=nullptr); 
  516  TObject* clone(const char *newname) const override { return new CLASS_NAME(*this, newname); } 
  521   int getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char *rangeName=nullptr) const override; 
  522   double analyticalIntegral(int code, const char *rangeName=nullptr) const override; 
  528   int getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, bool staticInitOK=true) const override; 
  529   void initGenerator(int code) override {} // optional pre-generation initialization 
  530   void generateEvent(int code) override; 
  534  hf << "" << std::endl ;
 
  537  for (std::size_t i=0 ; i<alist.size() ; i++) {
 
  539      hf << 
"  RooRealProxy " << alist[i] << 
" ;" << std::endl ;
 
  541      hf << 
"  RooCategoryProxy " << alist[i] << 
" ;" << std::endl ;
 
  546  double evaluate() const override; 
  547  void doEval(RooFit::EvalContext &) const override; 
  551  ClassDefOverride(CLASS_NAME, 1) // Your description goes here... 
  555namespace Experimental { 
  557void codegenImpl(CLASS_NAME &arg, CodegenContext &ctx); 
  559} // namespace Experimental 
  565  hf << "inline double CLASS_NAME_evaluate(" << 
listVars(alist, 
isCat) << 
")";
 
  572   // Support also using the imaginary unit 
  573   using namespace std::complex_literals; 
  574   // To be able to also comile C code, we define a variable that behaves like the "I" macro from C. 
  575   constexpr auto I = 1i; 
  580   // ENTER EXPRESSION IN TERMS OF VARIABLE ARGUMENTS HERE 
  583     << "   return " << expression << 
";" << std::endl
 
  587  hf << 
"\n#endif // CLASS_NAME_h";
 
  589  std::stringstream 
cf;
 
  591  cf << R
"(/***************************************************************************** 
  594 * This code was autogenerated by RooClassFactory                            * 
  595 *****************************************************************************/ 
  597// Your description goes here... 
  599#include "CLASS_NAME.h" 
  601#include <RooAbsReal.h> 
  602#include <RooAbsCategory.h> 
  604#include <Riostream.h> 
  610CLASS_NAME::CLASS_NAME(const char *name, const char *title, 
  614  for (std::size_t i=0 ; i<alist.size() ; i++) {
 
  616      cf << 
"                        RooAbsReal& _" << alist[i] ;
 
  618      cf << 
"                        RooAbsCategory& _" << alist[i] ;
 
  620    if (i<alist.size()-1) {
 
  629  cf << 
"   : BASE_NAME(name,title)," << std::endl ;
 
  632  for (std::size_t i=0 ; i<alist.size() ; i++) {
 
  633    cf << 
"   " << alist[i] << 
"(\"" << alist[i] << 
"\",\"" << alist[i] << 
"\",this,_" << alist[i] << 
")" ;
 
  634    if (i<alist.size()-1) {
 
  640  cf << 
"{" << std::endl
 
  644     << 
"CLASS_NAME::CLASS_NAME(CLASS_NAME const &other, const char *name)" << std::endl
 
  645     << 
"   : BASE_NAME(other,name)," << std::endl ;
 
  647  for (std::size_t i=0 ; i<alist.size() ; i++) {
 
  648    cf << 
"   " << alist[i] << 
"(\"" << alist[i] << 
"\",this,other." << alist[i] << 
")" ;
 
  649    if (i<alist.size()-1) {
 
  659     << 
"double CLASS_NAME::evaluate() const " << std::endl
 
  661     << 
"   return CLASS_NAME_evaluate(" << 
listVars(alist) << 
");" << std::endl
 
  664     << 
"void CLASS_NAME::doEval(RooFit::EvalContext &ctx) const" << std::endl
 
  668     << 
"   std::size_t n = ctx.output().size();\n" 
  669     << 
"   for (std::size_t i = 0; i < n; ++i) {\n" 
  670     << 
"      ctx.output()[i] = CLASS_NAME_evaluate(" << 
getFromVarSpans(alist) << 
");\n" 
  676   for (std::size_t i = 0; i < alist.size(); ++i) {
 
  678      if (i < alist.size() - 1) {
 
 
  683   cf << 
"void RooFit::Experimental::codegenImpl(CLASS_NAME &arg, RooFit::Experimental::CodegenContext &ctx)\n" 
  685      << 
"   ctx.addResult(&arg, ctx.buildCall(\"CLASS_NAME_evaluate\", " << 
varsGetters.str() << 
"));\n" 
  697      std::vector<char> buf(
bufSize);
 
  699      char* ptr = 
strtok(buf.data(),
":") ;
 
  703   ptr = 
strtok(
nullptr,
":") ;
 
  708int CLASS_NAME::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char */*rangeName*/) const 
  710   // Support also using the imaginary unit 
  711   using namespace std::complex_literals; 
  712   // To be able to also comile C code, we define a variable that behaves like the "I" macro from C. 
  713   constexpr auto I = 1i; 
  715   // LIST HERE OVER WHICH VARIABLES ANALYTICAL INTEGRATION IS SUPPORTED, 
  716   // ASSIGN A NUMERIC CODE FOR EACH SUPPORTED (SET OF) PARAMETERS. THE EXAMPLE 
  717   // BELOW ASSIGNS CODE 1 TO INTEGRATION OVER VARIABLE X YOU CAN ALSO 
  718   // IMPLEMENT MORE THAN ONE ANALYTICAL INTEGRAL BY REPEATING THE matchArgs 
  719   // EXPRESSION MULTIPLE TIMES. 
  724   cf << 
"   if (matchArgs(allVars,analVars," << 
intObs[
ii] << 
")) return " << 
ii+1 << 
" ; " << std::endl ;
 
  727      cf << 
"   // if (matchArgs(allVars,analVars,x)) return 1 ; " << std::endl ;
 
  730    cf << 
"   return 0 ; " << std::endl
 
  735       << R
"(double CLASS_NAME::analyticalIntegral(int code, const char *rangeName) const 
  737  // RETURN ANALYTICAL INTEGRAL DEFINED BY RETURN CODE ASSIGNED BY 
  738  // getAnalyticalIntegral(). THE MEMBER FUNCTION x.min(rangeName) AND 
  739  // x.max(rangeName) WILL RETURN THE INTEGRATION BOUNDARIES FOR EACH 
  745   cf << 
"   if (code==" << 
ii+1 << 
") { return (" << 
intExpr[
ii] << 
") ; } " << std::endl ;
 
  748      cf << 
"   // assert(code==1) ; " << std::endl
 
  749    << 
"   // return (x.max(rangeName)-x.min(rangeName)) ; " << std::endl ;
 
  752    cf << 
"   return 0 ; " << std::endl
 
  753       << 
"} " << std::endl;
 
  758int CLASS_NAME::getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, bool /*staticInitOK*/) const 
  760   // LIST HERE OVER WHICH VARIABLES INTERNAL GENERATION IS SUPPORTED, ASSIGN A 
  761   // NUMERIC CODE FOR EACH SUPPORTED (SET OF) PARAMETERS. THE EXAMPLE BELOW 
  762   // ASSIGNS CODE 1 TO INTEGRATION OVER VARIABLE X. YOU CAN ALSO IMPLEMENT 
  763   // MORE THAN ONE GENERATOR CONFIGURATION BY REPEATING THE matchArgs 
  764   // EXPRESSION MULTIPLE TIMES. IF THE FLAG staticInitOK IS TRUE, THEN IT IS 
  765   // SAFE TO PRECALCULATE INTERMEDIATE QUANTITIES IN initGenerator(), IF IT IS 
  766   // NOT SET THEN YOU SHOULD NOT ADVERTISE ANY GENERATOR METHOD THAT RELIES ON 
  767   // PRECALCULATIONS IN initGenerator(). 
  769   // if (matchArgs(directVars,generateVars,x)) return 1; 
  773void CLASS_NAME::generateEvent(int code) 
  775   // GENERATE SET OF OBSERVABLES DEFINED BY RETURN CODE ASSIGNED BY 
  776   // getGenerator(). RETURN THE GENERATED VALUES BY ASSIGNING THEM TO THE 
  777   // PROXY DATA MEMBERS THAT REPRESENT THE CHOSEN OBSERVABLES. 
  788   std::ofstream 
ohf(className + 
".h");
 
  789   std::ofstream 
ocf(className + 
".cxx");
 
  807                                  std::vector<std::string> args)
 
  813   if (args.size() < 2) {
 
  814      throw std::runtime_error(
Form(
"RooClassFactory::ClassFacIFace::create() ERROR: CEXPR requires at least 2 " 
  815                                    "arguments (expr,var,...), but only %u args found",
 
  823   expr[args[0].size() - 2] = 0;
 
  827   if (args.size() == 2) {
 
  831      for (
unsigned int i = 1; i < args.size(); i++) {
 
  838      className = 
Form(
"RooCFAuto%03d%s%s", 
classCounter, (
tn == 
"CEXPR") ? 
"Pdf" : 
"Func", 
ft.autoClassNamePostFix());
 
  852      throw std::runtime_error(
 
  853         Form(
"RooClassFactory::ClassFacIFace::create() ERROR creating %s %s with RooClassFactory",
 
  861   ft.ws().importClassCode(
ret->IsA());
 
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.
 
void replaceAll(std::string &inOut, std::string_view what, std::string_view with)