83 for (
unsigned int i = 0; i < collection.
size(); ++i) {
110 bool checkVariables) :
121 <<
" but only " << useList <<
" seem to be in use."
122 <<
"\n inputs: " << formula << std::endl;
146#if !defined(__GNUC__) || defined(__clang__) || (__GNUC__ > 4) || ( __GNUC__ == 4 && __GNUC_MINOR__ > 8)
147#define ROOFORMULA_HAVE_STD_REGEX
155 cxcoutD(
InputArguments) <<
"Preprocessing formula step 1: find category tags (catName::catState) in "
159 std::regex categoryReg(
"(\\w+)::(\\w+)");
160 std::map<std::string, int> categoryStates;
161 for (sregex_iterator matchIt = sregex_iterator(formula.begin(), formula.end(), categoryReg);
162 matchIt != sregex_iterator(); ++matchIt) {
163 assert(matchIt->size() == 3);
164 const std::string fullMatch = (*matchIt)[0];
165 const std::string catName = (*matchIt)[1];
166 const std::string catState = (*matchIt)[2];
171 <<
"' but a category '" << catName <<
"' cannot be found in the input variables." << endl;
175 if (!catVariable->hasLabel(catState)) {
177 <<
"' but the category '" << catName <<
"' does not seem to have the state '" << catState <<
"'." << endl;
178 throw std::invalid_argument(formula);
180 const int catNum = catVariable->lookupIndex(catState);
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);
283 }
catch (std::runtime_error&
e) {
285 <<
"\n" <<
e.what() << endl;
307 bool errorStat =
false;
314 if (arg->getStringAttribute(
"origName")) {
320 }
else if (mustReplaceAll) {
321 coutE(
LinkStateMgmt) << __func__ <<
": cannot find replacement for " << arg->GetName() << endl;
344 std::string
what =
"Formula ";
346 what +=
" didn't compile.";
347 throw std::runtime_error(
what);
350 std::vector<double> pars;
355 pars.push_back(cat.getCurrentIndex());
358 pars.push_back(real.getVal(nset));
371 os <<
indent <<
"--- RooFormula ---" << endl;
385 os << const_cast<RooFormula*>(
this)->eval(0) ;
412 os << IsA()->GetName() ;
421 os <<
"[ actualVars=";
423 os <<
" " << arg->GetName();
436 <<
"\n\t" << processedFormula
439 <<
"\n with the parameters " <<
_origList << endl;
441 auto theFormula = std::make_unique<TFormula>(
GetName(), processedFormula.c_str(),
false);
443 if (!theFormula || !theFormula->IsValid()) {
444 std::stringstream msg;
445 msg <<
"RooFormula '" <<
GetName() <<
"' did not compile or is invalid."
446 <<
"\nInput:\n\t" << formula
447 <<
"\nPassed over to TFormula:\n\t" << processedFormula << std::endl;
449 throw std::runtime_error(msg.str());
452 if (theFormula && theFormula->GetNdim() != 1) {
455 bool haveProblem =
false;
456 std::stringstream msg;
457 msg <<
"TFormula interprets the formula " << formula <<
" as " << theFormula->GetNdim() <<
"-dimensional with the variable(s) {";
458 for (
int i=1; i < theFormula->GetNdim(); ++i) {
459 const TString varName = theFormula->GetVarName(i);
464 msg << theFormula->GetVarName(i) <<
",";
467 msg <<
"}, which could not be supplied by RooFit."
468 <<
"\nThe formula must be modified, or those variables must be supplied in the list of variables." << std::endl;
470 throw std::invalid_argument(msg.str());
478#ifndef ROOFORMULA_HAVE_STD_REGEX
492 TString formulaTString = formula.c_str();
494 cxcoutD(
InputArguments) <<
"Preprocessing formula step 1: find category tags (catName::catState) in "
495 << formulaTString.
Data() << endl;
498 TPRegexp categoryReg(
"(\\w+)::(\\w+)");
499 std::map<std::string, int> categoryStates;
502 std::unique_ptr<TObjArray> matches(categoryReg.MatchS(formulaTString,
"", offset, 3));
503 if (matches->GetEntries() == 0)
506 std::string fullMatch =
static_cast<TObjString*
>(matches->At(0))->GetString().Data();
507 std::string catName =
static_cast<TObjString*
>(matches->At(1))->GetString().Data();
508 std::string catState =
static_cast<TObjString*
>(matches->At(2))->GetString().Data();
509 offset = formulaTString.
Index(categoryReg, offset) + fullMatch.size();
514 <<
"' but a category '" << catName <<
"' cannot be found in the input variables." << endl;
518 const RooCatType* catType = catVariable->lookupType(catState.c_str(),
false);
521 <<
"' but the category '" << catName <<
"' does not seem to have the state '" << catState <<
"'." << endl;
522 throw std::invalid_argument(formula);
524 const int catNum = catType->
getVal();
526 categoryStates[fullMatch] = catNum;
527 cxcoutD(
InputArguments) <<
"\n\t" << fullMatch <<
"\tname=" << catName <<
"\tstate=" << catState <<
"=" << catNum;
528 }
while (offset != -1);
532 for (
const auto& catState : categoryStates) {
533 std::stringstream replacement;
534 replacement << catState.second;
535 formulaTString.
ReplaceAll(catState.first.c_str(), replacement.str().c_str());
544 nsub = ordinalRegex.Substitute(formulaTString,
"x[$1]");
553 regex += var.GetName();
554 regex +=
"\\b([^[]|$)";
557 std::stringstream replacement;
558 replacement <<
"x[" << i <<
"]$1";
561 nsub2 = findParameterRegex.Substitute(formulaTString, replacement.str().c_str());
565 << var.GetName() <<
" --> " << replacement.str()
566 <<
"\n\t" << formulaTString.
Data() << endl;
571 return formulaTString.
Data();
584 std::set<unsigned int> matchedOrdinals;
585 TPRegexp newOrdinalRegex(
"\\bx\\[([0-9]+)\\]");
588 std::unique_ptr<TObjArray> matches(newOrdinalRegex.MatchS(formulaTString,
"", offset, 2));
589 if (matches->GetEntries() == 0)
592 std::string fullMatch =
static_cast<TObjString*
>(matches->At(0))->GetString().Data();
593 std::string ordinal =
static_cast<TObjString*
>(matches->At(1))->GetString().Data();
594 offset = formulaTString.
Index(newOrdinalRegex, offset) + fullMatch.size();
596 std::stringstream matchString(ordinal.c_str());
600 matchedOrdinals.insert(i);
601 }
while (offset != -1);
603 for (
unsigned int i : matchedOrdinals) {
615 TString internalReprT = internalRepr.c_str();
619 std::stringstream regexStr;
620 regexStr <<
"x\\[" << i <<
"\\]|@" << i;
621 TPRegexp regex(regexStr.str().c_str());
623 std::string replacement = std::string(
"[") + var.GetName() +
"]";
624 regex.Substitute(internalReprT, replacement.c_str());
627 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 base class for objects that represent a discrete value with a finite number of ...
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)
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
static void output(int code)