49using std::sregex_iterator;
57 for (std::size_t i = 0; i <
formula.size(); ++i) {
62 }
else if (!match &&
formula[i] ==
'@') {
76 for (std::string::size_type pos{};
inOut.npos != (pos =
inOut.find(
what.data(), pos,
what.length()));
77 pos +=
with.length()) {
87 static const std::regex
r{
"\\b"};
88 std::vector<bool> out(s.size() + 1);
90 for (
auto i = std::sregex_iterator(s.begin(), s.end(),
r); i != std::sregex_iterator(); ++i) {
92 out[
m.position()] =
true;
106 std::stringstream
ss;
109 return std::stod(arg.
GetName()) == std::stod(
ss.str());
110 }
catch (
const std::exception &) {
111 throw std::invalid_argument(std::string(
"RooConstVar named ") + arg.
GetName() +
112 " has a name or value that cannot be converted to a valid number");
120 for (
unsigned int i = 0; i <
varList.size(); ++i) {
133 exceptionSs <<
"Variable '" <<
varName <<
"' is not a valid argument for RooFormulaVar. "
134 <<
"Variables with a name that is a number can only be of type RooConstVar "
135 <<
"and have value equal to the name";
147 std::string::size_type next = pos +
varName.length();
177 <<
"Preprocessing formula: replace named references: " <<
varName <<
" --> " <<
replacement <<
"\n\t"
198 <<
"Preprocessing formula step 1: find category tags (catName::catState) in " <<
formula << std::endl;
201 static const std::regex
categoryReg(
"(\\w+)::(\\w+)");
206 const std::string
fullMatch = (*matchIt)[0];
207 const std::string
catName = (*matchIt)[1];
208 const std::string
catState = (*matchIt)[2];
213 <<
"Formula " <<
callerName <<
" uses '::' to reference a category state as '" <<
fullMatch
214 <<
"' but a category '" <<
catName <<
"' cannot be found in the input variables." << std::endl;
220 <<
"Formula " <<
callerName <<
" uses '::' to reference a category state as '" <<
fullMatch
221 <<
"' but the category '" <<
catName <<
"' does not seem to have the state '" <<
catState <<
"'."
223 throw std::invalid_argument(
formula);
231 oocxcoutD(
static_cast<TObject *
>(
nullptr), InputArguments) <<
"-- End of category tags --" << std::endl;
239 <<
"Preprocessing formula step 2: replace category tags\n\t" <<
formula << std::endl;
245 <<
"Preprocessing formula step 3: replace '@'-references\n\t" <<
formula << std::endl;
266 static const std::regex
ordinalRegex(
"\\bx\\[([0-9]+)\\]");
272 const std::size_t i = std::stoi((*
matchIt)[1].str());
281 for (std::size_t i = 0; i <
varList.size(); ++i) {
296 const std::size_t
oldIdx = std::stoi(match[1].str());
298 lastPos = match.position() + match.length();
315 for (
unsigned int i = 0; i <
nArgs; ++i) {
317 regexStr <<
"x\\[" << i <<
"\\]|@" << i;
331std::unique_ptr<RooFormulaEvaluator>
336 <<
"RooFormula '" <<
name <<
"' will be compiled as "
348std::unique_ptr<RooFormulaEvaluator>
349RooFormulaUtils::makeFormulaEvaluator(std::string
const &
name, std::string
const &expression,
RooArgList const &
varList)
359void RooFormulaUtils::initFormula(std::unique_ptr<RooFormulaEvaluator> &evaluator,
TString &
formExpr,
375RooFormulaEvaluator &RooFormulaUtils::ensureEvaluator(std::unique_ptr<RooFormulaEvaluator> &evaluator,
393 std::unique_ptr<RooFormulaEvaluator> out =
other.clone();
407 std::vector<double> pars;
408 pars.reserve(vars.
size());
412 pars.push_back(cat.getCurrentIndex());
415 pars.push_back(
real.getVal(nset));
419 return evaluator.eval(pars.data());
428 std::span<double> output =
ctx.output();
434 std::vector<std::span<const double>>
inputSpans;
436 for (std::size_t i = 0; i <
nPars; ++i) {
440 std::vector<double> pars(
nPars);
441 for (std::size_t i = 0; i < output.size(); ++i) {
442 for (std::size_t
j = 0;
j <
nPars; ++
j) {
445 output[i] = evaluator.eval(pars.data());
454 os <<
indent <<
"--- RooFormula ---" << std::endl;
455 os <<
indent <<
" Formula: '" <<
formula <<
"'" << std::endl;
467 out[
item.first] = std::unique_ptr<RooAbsBinning>{
item.second->clone()};
484 <<
") the observable " << obs.
GetName()
485 <<
" is not one of the formula variables, nothing done." << std::endl;
494 std::span<const double> boundaries{binning.
array(),
static_cast<std::size_t
>(binning.
numBoundaries())};
497 <<
caller.ClassName() <<
"::setBinning(" <<
caller.GetName() <<
") the expression \"" <<
formExpr
498 <<
"\" is not flat within the given bins of " << obs.
GetName()
499 <<
". The binning is not set. Pass checkFlatness=false to override this check." << std::endl;
508 binnings[idx] = std::unique_ptr<RooAbsBinning>{binning.
clone()};
518 return found !=
binnings.
end() ? found->second.get() :
nullptr;
531 const int idx =
actualVars.index(o->GetName());
558 auto hint =
new std::list<double>;
static void indent(ostringstream &buf, int indent_level)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 r
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 result
const_iterator begin() const
const_iterator end() const
Common abstract base class for objects that represent a value and a "shape" in RooFit.
virtual bool isCategory() const
Abstract base class for RooRealVar binning definitions.
virtual Int_t numBoundaries() const =0
virtual double * array() const =0
virtual RooAbsBinning * clone(const char *name=nullptr) const =0
A space to attach TBranches.
Abstract container object that can hold multiple RooAbsArg objects.
const char * GetName() const override
Returns name of object.
Storage_t::size_type size() const
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
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.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
static std::list< double > * plotSamplingHintForBinBoundaries(std::span< const double > boundaries, double xlo, double xhi)
Returns sampling hints for a histogram with given boundaries.
const char * GetName() const override
Returns name of object.
Mother of all ROOT objects.
void replaceAll(std::string &inOut, std::string_view what, std::string_view with)
bool isFunctionFlatInBins(const RooAbsReal &function, RooAbsRealLValue &obs, std::span< const double > boundaries, double relTol=1e-9)
Check that function is constant (flat) inside each bin defined by the sorted boundaries when scanning...