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.