91 bool checkVariables) :
100 <<
"\n\t" << processedFormula
103 <<
"\n with the parameters " <<
_origList << endl;
106 if (!processedFormula.empty())
107 _tFormula = std::make_unique<TFormula>(
name, processedFormula.c_str(),
false);
111 <<
"\nInput:\n\t" << formula
112 <<
"\nProcessed:\n\t" << processedFormula << endl;
119 <<
" but only " << useList <<
" seem to be in use."
120 <<
"\n inputs: " << formula
145#if !defined(__GNUC__) || defined(__clang__) || (__GNUC__ > 4) || ( __GNUC__ == 4 && __GNUC_MINOR__ > 8)
146#define ROOFORMULA_HAVE_STD_REGEX
154 cxcoutD(
InputArguments) <<
"Preprocessing formula step 1: find category tags (catName::catState) in "
158 std::regex categoryReg(
"(\\w+)::(\\w+)");
159 std::map<std::string, int> categoryStates;
160 for (sregex_iterator matchIt = sregex_iterator(formula.begin(), formula.end(), categoryReg);
161 matchIt != sregex_iterator(); ++matchIt) {
162 assert(matchIt->size() == 3);
163 const std::string fullMatch = (*matchIt)[0];
164 const std::string catName = (*matchIt)[1];
165 const std::string catState = (*matchIt)[2];
170 <<
"' but a category '" << catName <<
"' cannot be found in the input variables." << endl;
174 const RooCatType* catType = catVariable->lookupType(catState.c_str(),
false);
177 <<
"' but the category '" << catName <<
"' does not seem to have the state '" << catState <<
"'." << endl;
178 throw std::invalid_argument(formula);
180 const int catNum = catType->
getVal();
182 categoryStates[fullMatch] = catNum;
183 cxcoutD(
InputArguments) <<
"\n\t" << fullMatch <<
"\tname=" << catName <<
"\tstate=" << catState <<
"=" << catNum;
188 for (
const auto& catState : categoryStates) {
189 std::stringstream replacement;
190 replacement << catState.second;
191 formula = std::regex_replace(formula, std::regex(catState.first), replacement.str());
194 cxcoutD(
InputArguments) <<
"Preprocessing formula step 2: replace category tags\n\t" << formula << endl;
197 std::regex ordinalRegex(
"@([0-9]+)");
198 formula = std::regex_replace(formula, ordinalRegex,
"x[$1]");
200 cxcoutD(
InputArguments) <<
"Preprocessing formula step 3: replace '@'-references\n\t" << formula << endl;
205 auto regex = std::string{
"\\b"} + var.
GetName();
206 regex = std::regex_replace(regex, std::regex(
"([\\[\\]\\{\\}])"),
"\\$1");
207 regex +=
"\\b(?!\\[)";
208 std::regex findParameterRegex(regex);
210 std::stringstream replacement;
211 replacement <<
"x[" << i <<
"]";
212 formula = std::regex_replace(formula, findParameterRegex, replacement.str());
215 << var.GetName() <<
" --> " << replacement.str()
216 <<
"\n\t" << formula << endl;
232 const std::string formula(
_tFormula->GetTitle());
234 std::set<unsigned int> matchedOrdinals;
235 std::regex newOrdinalRegex(
"\\bx\\[([0-9]+)\\]");
236 for (sregex_iterator matchIt = sregex_iterator(formula.begin(), formula.end(), newOrdinalRegex);
237 matchIt != sregex_iterator(); ++matchIt) {
238 assert(matchIt->size() == 2);
239 std::stringstream matchString((*matchIt)[1]);
243 matchedOrdinals.insert(i);
246 for (
unsigned int i : matchedOrdinals) {
260 std::stringstream regexStr;
261 regexStr <<
"x\\[" << i <<
"\\]|@" << i;
262 std::regex regex(regexStr.str());
264 std::string replacement = std::string(
"[") + var.GetName() +
"]";
265 internalRepr = std::regex_replace(internalRepr, regex, replacement);
279 for (
unsigned int i = 0; i < collection.
size(); ++i) {
293 auto newTF = std::make_unique<TFormula>(
GetName(), processed.c_str(),
false);
295 if (!newTF->IsValid()) {
296 coutE(
InputArguments) << __func__ <<
": new equation doesn't compile, formula unchanged" << endl;
319 bool errorStat =
false;
326 if (arg->getStringAttribute(
"origName")) {
332 }
else if (mustReplaceAll) {
333 coutE(
LinkStateMgmt) << __func__ <<
": cannot find replacement for " << arg->GetName() << endl;
356 std::string what =
"Formula ";
358 what +=
" didn't compile.";
359 throw std::invalid_argument(what);
362 std::vector<double> pars;
367 pars.push_back(cat.getIndex());
370 pars.push_back(real.getVal(nset));
383 os <<
indent <<
"--- RooFormula ---" << endl;
397 os << const_cast<RooFormula*>(
this)->eval(0) ;
424 os << IsA()->GetName() ;
433 os <<
"[ actualVars=";
435 os <<
" " << arg->GetName();
444#ifndef ROOFORMULA_HAVE_STD_REGEX
458 TString formulaTString = formula.c_str();
460 cxcoutD(
InputArguments) <<
"Preprocessing formula step 1: find category tags (catName::catState) in "
461 << formulaTString.
Data() << endl;
464 TPRegexp categoryReg(
"(\\w+)::(\\w+)");
465 std::map<std::string, int> categoryStates;
468 std::unique_ptr<TObjArray> matches(categoryReg.MatchS(formulaTString,
"", offset, 3));
469 if (matches->GetEntries() == 0)
472 std::string fullMatch =
static_cast<TObjString*
>(matches->At(0))->GetString().Data();
473 std::string catName =
static_cast<TObjString*
>(matches->At(1))->GetString().Data();
474 std::string catState =
static_cast<TObjString*
>(matches->At(2))->GetString().Data();
475 offset = formulaTString.
Index(categoryReg, offset) + fullMatch.size();
480 <<
"' but a category '" << catName <<
"' cannot be found in the input variables." << endl;
484 const RooCatType* catType = catVariable->lookupType(catState.c_str(),
false);
487 <<
"' but the category '" << catName <<
"' does not seem to have the state '" << catState <<
"'." << endl;
488 throw std::invalid_argument(formula);
490 const int catNum = catType->
getVal();
492 categoryStates[fullMatch] = catNum;
493 cxcoutD(
InputArguments) <<
"\n\t" << fullMatch <<
"\tname=" << catName <<
"\tstate=" << catState <<
"=" << catNum;
494 }
while (offset != -1);
498 for (
const auto& catState : categoryStates) {
499 std::stringstream replacement;
500 replacement << catState.second;
501 formulaTString.
ReplaceAll(catState.first.c_str(), replacement.str().c_str());
510 nsub = ordinalRegex.Substitute(formulaTString,
"x[$1]");
519 regex += var.GetName();
520 regex +=
"\\b([^[]|$)";
523 std::stringstream replacement;
524 replacement <<
"x[" << i <<
"]$1";
527 nsub2 = findParameterRegex.Substitute(formulaTString, replacement.str().c_str());
531 << var.GetName() <<
" --> " << replacement.str()
532 <<
"\n\t" << formulaTString.
Data() << endl;
537 return formulaTString.
Data();
550 std::set<unsigned int> matchedOrdinals;
551 TPRegexp newOrdinalRegex(
"\\bx\\[([0-9]+)\\]");
554 std::unique_ptr<TObjArray> matches(newOrdinalRegex.MatchS(formulaTString,
"", offset, 2));
555 if (matches->GetEntries() == 0)
558 std::string fullMatch =
static_cast<TObjString*
>(matches->At(0))->GetString().Data();
559 std::string ordinal =
static_cast<TObjString*
>(matches->At(1))->GetString().Data();
560 offset = formulaTString.
Index(newOrdinalRegex, offset) + fullMatch.size();
562 std::stringstream matchString(ordinal.c_str());
566 matchedOrdinals.insert(i);
567 }
while (offset != -1);
569 for (
unsigned int i : matchedOrdinals) {
581 TString internalReprT = internalRepr.c_str();
585 std::stringstream regexStr;
586 regexStr <<
"x\\[" << i <<
"\\]|@" << i;
587 TPRegexp regex(regexStr.str().c_str());
589 std::string replacement = std::string(
"[") + var.GetName() +
"]";
590 regex.Substitute(internalReprT, replacement.c_str());
593 return internalReprT.
Data();
static void indent(ostringstream &buf, int indent_level)
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
RooAbsArg * findNewServer(const RooAbsCollection &newSet, Bool_t nameChange) const
Find the new server in the specified set that matches the old server.
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
virtual Bool_t replace(const RooAbsArg &var1, const RooAbsArg &var2)
Replace var1 with var2 and return kTRUE for success.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
Storage_t::size_type size() const
const char * GetName() const
Returns name of object.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooCatType is an auxilary class for RooAbsCategory and defines a a single category state.
RooPlotable is a 'mix-in' base class that define the standard RooFit plotting and printing methods.
The TNamed class is the base class for all named ROOT classes.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
virtual const char * GetTitle() const
Returns title of object.
virtual const char * GetName() const
Returns name of object.
Collectable string class.
const char * Data() const
TString & ReplaceAll(const TString &s1, const TString &s2)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
std::string GetName(const std::string &scope_name)
static void output(int code)