Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooFormula.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17/**
18\file RooFormula.cxx
19\class RooFormula
20\ingroup Roofitcore
21
22RooFormula internally uses ROOT's TFormula to compute user-defined expressions
23of RooAbsArgs.
24
25The string expression can be any valid TFormula expression referring to the
26listed servers either by name or by their ordinal list position. These three are
27forms equivalent:
28```
29 RooFormula("formula", "x*y", RooArgList(x,y)) or
30 RooFormula("formula", "@0*@1", RooArgList(x,y))
31 RooFormula("formula", "x[0]*x[1]", RooArgList(x,y))
32```
33Note that `x[i]` is an expression reserved for TFormula. If a variable with
34the name `x` is given, the RooFormula interprets `x` as a variable name,
35but `x[i]` as an index in the list of variables.
36
37### Category expressions
38State information of RooAbsCategories can be accessed using the '::' operator,
39*i.e.*, `tagCat::Kaon` will resolve to the numerical value of
40the `Kaon` state of the RooAbsCategory object named `tagCat`.
41
42A formula to switch between lepton categories could look like this:
43```
44 RooFormula("formulaWithCat",
45 "x * (leptonMulti == leptonMulti::one) + y * (leptonMulti == leptonMulti::two)",
46 RooArgList(x, y, leptonMulti));
47```
48
49### Debugging a formula that won't compile
50When the formula is preprocessed, RooFit can print information in the debug stream.
51These can be retrieved by activating the RooFit::MsgLevel `RooFit::DEBUG`
52and the RooFit::MsgTopic `RooFit::InputArguments`.
53Check the tutorial rf506_msgservice.C for details.
54**/
55
56#include "RooFormula.h"
57
58#include "RooFit.h"
59#include "RooAbsReal.h"
60#include "RooAbsCategory.h"
61#include "RooArgList.h"
62#include "RooMsgService.h"
63#include "RooBatchCompute.h"
64
65#include "ROOT/RMakeUnique.hxx"
66#include "TObjString.h"
67#include "TClass.h"
68
69#include <sstream>
70#include <regex>
71
72using namespace std;
73
75
76namespace {
77
78////////////////////////////////////////////////////////////////////////////////
79/// Find all input arguments which are categories, and save this information in
80/// with the names of the variables that are being used to evaluate it.
81std::vector<bool> findCategoryServers(const RooAbsCollection& collection) {
82 std::vector<bool> output;
83 output.reserve(collection.size());
84
85 for (unsigned int i = 0; i < collection.size(); ++i) {
86 output.push_back(collection[i]->InheritsFrom(RooAbsCategory::Class()));
87 }
88
89 return output;
90}
91
92}
93
94////////////////////////////////////////////////////////////////////////////////
95/// Default constructor
96/// coverity[UNINIT_CTOR]
97
99{
100}
101
102
103////////////////////////////////////////////////////////////////////////////////
104/// Construct a new formula.
105/// \param[in] name Name of the formula.
106/// \param[in] formula Formula to be evaluated. Parameters/observables are identified by name
107/// or ordinal position in `varList`.
108/// \param[in] varList List of variables to be passed to the formula.
109/// \param[in] checkVariables Check that the variables being passed in the `varList` are used in
110/// the formula expression.
111RooFormula::RooFormula(const char* name, const char* formula, const RooArgList& varList,
112 bool checkVariables) :
113 TNamed(name, formula), _tFormula{nullptr}
114{
115 _origList.add(varList);
116 _isCategory = findCategoryServers(_origList);
117
118 installFormulaOrThrow(formula);
119
120 RooArgList useList = usedVariables();
121 if (checkVariables && _origList.size() != useList.size()) {
122 coutI(InputArguments) << "The formula " << GetName() << " claims to use the variables " << _origList
123 << " but only " << useList << " seem to be in use."
124 << "\n inputs: " << formula << std::endl;
125 }
126}
127
128
129
130////////////////////////////////////////////////////////////////////////////////
131/// Copy constructor
132RooFormula::RooFormula(const RooFormula& other, const char* name) :
133 TNamed(name ? name : other.GetName(), other.GetTitle()), RooPrintable(other)
134{
135 _origList.add(other._origList);
136 _isCategory = findCategoryServers(_origList);
137
138 TFormula* newTF = nullptr;
139 if (other._tFormula) {
140 newTF = new TFormula(*other._tFormula);
141 newTF->SetName(GetName());
142 }
143
144 _tFormula.reset(newTF);
145}
146
147#ifndef _MSC_VER
148#if !defined(__GNUC__) || defined(__clang__) || (__GNUC__ > 4) || ( __GNUC__ == 4 && __GNUC_MINOR__ > 8)
149#define ROOFORMULA_HAVE_STD_REGEX
150////////////////////////////////////////////////////////////////////////////////
151/// Process given formula by replacing all ordinal and name references by
152/// `x[i]`, where `i` matches the position of the argument in `_origList`.
153/// Further, references to category states such as `leptonMulti:one` are replaced
154/// by the category index.
155std::string RooFormula::processFormula(std::string formula) const {
156
157 cxcoutD(InputArguments) << "Preprocessing formula step 1: find category tags (catName::catState) in "
158 << formula << endl;
159
160 // Step 1: Find all category tags and the corresponding index numbers
161 std::regex categoryReg("(\\w+)::(\\w+)");
162 std::map<std::string, int> categoryStates;
163 for (sregex_iterator matchIt = sregex_iterator(formula.begin(), formula.end(), categoryReg);
164 matchIt != sregex_iterator(); ++matchIt) {
165 assert(matchIt->size() == 3);
166 const std::string fullMatch = (*matchIt)[0];
167 const std::string catName = (*matchIt)[1];
168 const std::string catState = (*matchIt)[2];
169
170 const auto catVariable = dynamic_cast<const RooAbsCategory*>(_origList.find(catName.c_str()));
171 if (!catVariable) {
172 cxcoutD(InputArguments) << "Formula " << GetName() << " uses '::' to reference a category state as '" << fullMatch
173 << "' but a category '" << catName << "' cannot be found in the input variables." << endl;
174 continue;
175 }
176
177 if (!catVariable->hasLabel(catState)) {
178 coutE(InputArguments) << "Formula " << GetName() << " uses '::' to reference a category state as '" << fullMatch
179 << "' but the category '" << catName << "' does not seem to have the state '" << catState << "'." << endl;
180 throw std::invalid_argument(formula);
181 }
182 const int catNum = catVariable->lookupIndex(catState);
183
184 categoryStates[fullMatch] = catNum;
185 cxcoutD(InputArguments) << "\n\t" << fullMatch << "\tname=" << catName << "\tstate=" << catState << "=" << catNum;
186 }
187 cxcoutD(InputArguments) << "-- End of category tags --"<< endl;
188
189 // Step 2: Replace all category tags
190 for (const auto& catState : categoryStates) {
191 std::stringstream replacement;
192 replacement << catState.second;
193 formula = std::regex_replace(formula, std::regex(catState.first), replacement.str());
194 }
195
196 cxcoutD(InputArguments) << "Preprocessing formula step 2: replace category tags\n\t" << formula << endl;
197
198 // Step 3: Convert `@i`-style references to `x[i]`
199 std::regex ordinalRegex("@([0-9]+)");
200 formula = std::regex_replace(formula, ordinalRegex, "x[$1]");
201
202 cxcoutD(InputArguments) << "Preprocessing formula step 3: replace '@'-references\n\t" << formula << endl;
203
204 // Step 4: Replace all named references with "x[i]"-style
205 for (unsigned int i = 0; i < _origList.size(); ++i) {
206 const auto& var = _origList[i];
207 auto regex = std::string{"\\b"} + var.GetName();
208 regex = std::regex_replace(regex, std::regex("([\\[\\]\\{\\}])"), "\\$1"); // The name might contain [, ], {, or }.
209 regex += "\\b(?!\\[)"; // Veto '[' as next character. If the variable is called `x`, this might otherwise replace `x[0]`.
210 std::regex findParameterRegex(regex);
211
212 std::stringstream replacement;
213 replacement << "x[" << i << "]";
214 formula = std::regex_replace(formula, findParameterRegex, replacement.str());
215
216 cxcoutD(InputArguments) << "Preprocessing formula step 4: replace named references: "
217 << var.GetName() << " --> " << replacement.str()
218 << "\n\t" << formula << endl;
219 }
220
221 cxcoutD(InputArguments) << "Final formula:\n\t" << formula << endl;
222
223 return formula;
224}
225
226
227////////////////////////////////////////////////////////////////////////////////
228/// Analyse internal formula to find out which variables are actually in use.
230 RooArgList useList;
231 if (_tFormula == nullptr)
232 return useList;
233
234 const std::string formula(_tFormula->GetTitle());
235
236 std::set<unsigned int> matchedOrdinals;
237 std::regex newOrdinalRegex("\\bx\\[([0-9]+)\\]");
238 for (sregex_iterator matchIt = sregex_iterator(formula.begin(), formula.end(), newOrdinalRegex);
239 matchIt != sregex_iterator(); ++matchIt) {
240 assert(matchIt->size() == 2);
241 std::stringstream matchString((*matchIt)[1]);
242 unsigned int i;
243 matchString >> i;
244
245 matchedOrdinals.insert(i);
246 }
247
248 for (unsigned int i : matchedOrdinals) {
249 useList.add(_origList[i]);
250 }
251
252 return useList;
253}
254
255
256////////////////////////////////////////////////////////////////////////////////
257/// From the internal representation, construct a formula by replacing all index place holders
258/// with the names of the variables that are being used to evaluate it.
259std::string RooFormula::reconstructFormula(std::string internalRepr) const {
260 for (unsigned int i = 0; i < _origList.size(); ++i) {
261 const auto& var = _origList[i];
262 std::stringstream regexStr;
263 regexStr << "x\\[" << i << "\\]|@" << i;
264 std::regex regex(regexStr.str());
265
266 std::string replacement = std::string("[") + var.GetName() + "]";
267 internalRepr = std::regex_replace(internalRepr, regex, replacement);
268 }
269
270 return internalRepr;
271}
272#endif //GCC < 4.9 Check
273#endif //_MSC_VER
274
275
276
277
278////////////////////////////////////////////////////////////////////////////////
279/// Recompile formula with new expression. In case of error, the old formula is
280/// retained.
281Bool_t RooFormula::reCompile(const char* newFormula)
282{
283 try {
284 installFormulaOrThrow(newFormula);
285 } catch (std::runtime_error& e) {
286 coutE(InputArguments) << __func__ << ": new equation doesn't compile, formula unchanged."
287 << "\n" << e.what() << endl;
288 return true;
289 }
290
291 SetTitle(newFormula);
292 return false;
293}
294
296{
297 printMultiline(std::cout, 0);
298}
299
300
301////////////////////////////////////////////////////////////////////////////////
302/// Change used variables to those with the same name in given list.
303/// \param[in] newDeps New dependents to replace the old ones.
304/// \param[in] mustReplaceAll Will yield an error if one dependent does not have a replacement.
305/// \param[in] nameChange Passed down to RooAbsArg::findNewServer(const RooAbsCollection&, Bool_t) const.
306Bool_t RooFormula::changeDependents(const RooAbsCollection& newDeps, Bool_t mustReplaceAll, Bool_t nameChange)
307{
308 //Change current servers to new servers with the same name given in list
309 bool errorStat = false;
310
311 for (const auto arg : _origList) {
312 RooAbsReal* replace = (RooAbsReal*) arg->findNewServer(newDeps,nameChange) ;
313 if (replace) {
314 _origList.replace(*arg, *replace);
315
316 if (arg->getStringAttribute("origName")) {
317 replace->setStringAttribute("origName",arg->getStringAttribute("origName")) ;
318 } else {
319 replace->setStringAttribute("origName",arg->GetName()) ;
320 }
321
322 } else if (mustReplaceAll) {
323 coutE(LinkStateMgmt) << __func__ << ": cannot find replacement for " << arg->GetName() << endl;
324 errorStat = true;
325 }
326 }
327
328 _isCategory = findCategoryServers(_origList);
329
330 return errorStat;
331}
332
333
334
335////////////////////////////////////////////////////////////////////////////////
336/// Evaluate the internal TFormula.
337///
338/// First, all variables serving this instance are evaluated given the normalisation set,
339/// and then the formula is evaluated.
340/// \param[in] nset Normalisation set passed to evaluation of arguments serving values.
341/// \return The result of the evaluation.
343{
344 if (!_tFormula) {
345 coutF(Eval) << __func__ << " (" << GetName() << "): Formula didn't compile: " << GetTitle() << endl;
346 std::string what = "Formula ";
347 what += GetTitle();
348 what += " didn't compile.";
349 throw std::runtime_error(what);
350 }
351
352 std::vector<double> pars;
353 pars.reserve(_origList.size());
354 for (unsigned int i = 0; i < _origList.size(); ++i) {
355 if (_isCategory[i]) {
356 const auto& cat = static_cast<RooAbsCategory&>(_origList[i]);
357 pars.push_back(cat.getCurrentIndex());
358 } else {
359 const auto& real = static_cast<RooAbsReal&>(_origList[i]);
360 pars.push_back(real.getVal(nset));
361 }
362 }
363
364 return _tFormula->EvalPar(pars.data());
365}
366
367
369 if (!_tFormula) {
370 coutF(Eval) << __func__ << " (" << GetName() << "): Formula didn't compile: " << GetTitle() << endl;
371 std::string what = "Formula ";
372 what += GetTitle();
373 what += " didn't compile.";
374 throw std::runtime_error(what);
375 }
376
377 std::vector<RooBatchCompute::BracketAdapterWithMask> valueAdapters;
378 std::vector<RooSpan<const double>> inputSpans;
379 size_t nData=1;
380 for (const auto arg : _origList) {
381 auto realArg = static_cast<const RooAbsReal*>(arg);
382 auto batch = realArg->getValues(inputData, nset);
383 assert(!batch.empty());
384 nData = std::max(nData, batch.size());
385 valueAdapters.emplace_back(batch[0], batch);
386 inputSpans.push_back(std::move(batch));
387 }
388
389 auto output = inputData.makeBatch(dataOwner, nData);
390 std::vector<double> pars(_origList.size());
391
392
393 for (std::size_t i=0; i < nData; ++i) {
394 for (unsigned int j=0; j < _origList.size(); ++j) {
395 if (_isCategory[j]) {
396 // TODO: As long as category states cannot be passed in the RunContext,
397 // the current state has to be used.
398 const auto& cat = static_cast<RooAbsCategory&>(_origList[j]);
399 pars[j] = cat.getCurrentIndex();
400 } else {
401 pars[j] = valueAdapters[j][i];
402 }
403 }
404
405 output[i] = _tFormula->EvalPar(pars.data());
406 }
407
408 return output;
409}
410
411////////////////////////////////////////////////////////////////////////////////
412/// Printing interface
413
414void RooFormula::printMultiline(ostream& os, Int_t /*contents*/, Bool_t /*verbose*/, TString indent) const
415{
416 os << indent << "--- RooFormula ---" << endl;
417 os << indent << " Formula: '" << GetTitle() << "'" << endl;
418 os << indent << " Interpretation: '" << reconstructFormula(GetTitle()) << "'" << endl;
419 indent.Append(" ");
420 os << indent << "Servers: " << _origList << "\n";
421 os << indent << "In use : " << actualDependents() << endl;
422}
423
424
425////////////////////////////////////////////////////////////////////////////////
426/// Print value of formula
427
428void RooFormula::printValue(ostream& os) const
429{
430 os << const_cast<RooFormula*>(this)->eval(0) ;
431}
432
433
434////////////////////////////////////////////////////////////////////////////////
435/// Print name of formula
436
437void RooFormula::printName(ostream& os) const
438{
439 os << GetName() ;
440}
441
442
443////////////////////////////////////////////////////////////////////////////////
444/// Print title of formula
445
446void RooFormula::printTitle(ostream& os) const
447{
448 os << GetTitle() ;
449}
450
451
452////////////////////////////////////////////////////////////////////////////////
453/// Print class name of formula
454
455void RooFormula::printClassName(ostream& os) const
456{
457 os << IsA()->GetName() ;
458}
459
460
461////////////////////////////////////////////////////////////////////////////////
462/// Print arguments of formula, i.e. dependents that are actually used
463
464void RooFormula::printArgs(ostream& os) const
465{
466 os << "[ actualVars=";
467 for (const auto arg : usedVariables()) {
468 os << " " << arg->GetName();
469 }
470 os << " ]";
471}
472
473
474////////////////////////////////////////////////////////////////////////////////
475/// Check that the formula compiles, and also fulfills the assumptions.
476///
477void RooFormula::installFormulaOrThrow(const std::string& formula) {
478 const std::string processedFormula = processFormula(formula);
479
480 cxcoutD(InputArguments) << "RooFormula '" << GetName() << "' will be compiled as "
481 << "\n\t" << processedFormula
482 << "\n and used as"
483 << "\n\t" << reconstructFormula(processedFormula)
484 << "\n with the parameters " << _origList << endl;
485
486 auto theFormula = std::make_unique<TFormula>(GetName(), processedFormula.c_str(), false);
487
488 if (!theFormula || !theFormula->IsValid()) {
489 std::stringstream msg;
490 msg << "RooFormula '" << GetName() << "' did not compile or is invalid."
491 << "\nInput:\n\t" << formula
492 << "\nPassed over to TFormula:\n\t" << processedFormula << std::endl;
493 coutF(InputArguments) << msg.str();
494 throw std::runtime_error(msg.str());
495 }
496
497 if (theFormula && theFormula->GetNdim() != 1) {
498 // TFormula thinks that we have a multi-dimensional formula, e.g. with variables x,y,z,t.
499 // We have to check now that this is not the case, as RooFit only uses the syntax x[0], x[1], x[2], ...
500 bool haveProblem = false;
501 std::stringstream msg;
502 msg << "TFormula interprets the formula " << formula << " as " << theFormula->GetNdim() << "-dimensional with the variable(s) {";
503 for (int i=1; i < theFormula->GetNdim(); ++i) {
504 const TString varName = theFormula->GetVarName(i);
505 if (varName.BeginsWith("x[") && varName[varName.Length()-1] == ']')
506 continue;
507
508 haveProblem = true;
509 msg << theFormula->GetVarName(i) << ",";
510 }
511 if (haveProblem) {
512 msg << "}, which could not be supplied by RooFit."
513 << "\nThe formula must be modified, or those variables must be supplied in the list of variables." << std::endl;
514 coutF(InputArguments) << msg.str();
515 throw std::invalid_argument(msg.str());
516 }
517 }
518
519 _tFormula = std::move(theFormula);
520}
521
522
523#ifndef ROOFORMULA_HAVE_STD_REGEX
524/*
525 * g++ 4.8 doesn't support the std::regex. It has headers, but no implementations of the standard, leading to linker
526 * errors. As long as centos 7 needs to be supported, this forces us to have a legacy implementation.
527 */
528
529#include "TPRegexp.h"
530
531////////////////////////////////////////////////////////////////////////////////
532/// Process given formula by replacing all ordinal and name references by
533/// `x[i]`, where `i` matches the position of the argument in `_origList`.
534/// Further, references to category states such as `leptonMulti:one` are replaced
535/// by the category index.
536std::string RooFormula::processFormula(std::string formula) const {
537 TString formulaTString = formula.c_str();
538
539 cxcoutD(InputArguments) << "Preprocessing formula step 1: find category tags (catName::catState) in "
540 << formulaTString.Data() << endl;
541
542 // Step 1: Find all category tags and the corresponding index numbers
543 TPRegexp categoryReg("(\\w+)::(\\w+)");
544 std::map<std::string, int> categoryStates;
545 int offset = 0;
546 do {
547 std::unique_ptr<TObjArray> matches(categoryReg.MatchS(formulaTString, "", offset, 3));
548 if (matches->GetEntries() == 0)
549 break;
550
551 std::string fullMatch = static_cast<TObjString*>(matches->At(0))->GetString().Data();
552 std::string catName = static_cast<TObjString*>(matches->At(1))->GetString().Data();
553 std::string catState = static_cast<TObjString*>(matches->At(2))->GetString().Data();
554 offset = formulaTString.Index(categoryReg, offset) + fullMatch.size();
555
556 const auto catVariable = dynamic_cast<const RooAbsCategory*>(_origList.find(catName.c_str()));
557 if (!catVariable) {
558 cxcoutD(InputArguments) << "Formula " << GetName() << " uses '::' to reference a category state as '" << fullMatch
559 << "' but a category '" << catName << "' cannot be found in the input variables." << endl;
560 continue;
561 }
562
563 const RooCatType* catType = catVariable->lookupType(catState.c_str(), false);
564 if (!catType) {
565 coutE(InputArguments) << "Formula " << GetName() << " uses '::' to reference a category state as '" << fullMatch
566 << "' but the category '" << catName << "' does not seem to have the state '" << catState << "'." << endl;
567 throw std::invalid_argument(formula);
568 }
569 const int catNum = catType->getVal();
570
571 categoryStates[fullMatch] = catNum;
572 cxcoutD(InputArguments) << "\n\t" << fullMatch << "\tname=" << catName << "\tstate=" << catState << "=" << catNum;
573 } while (offset != -1);
574 cxcoutD(InputArguments) << "-- End of category tags --"<< endl;
575
576 // Step 2: Replace all category tags
577 for (const auto& catState : categoryStates) {
578 std::stringstream replacement;
579 replacement << catState.second;
580 formulaTString.ReplaceAll(catState.first.c_str(), replacement.str().c_str());
581 }
582
583 cxcoutD(InputArguments) << "Preprocessing formula step 2: replace category tags\n\t" << formulaTString.Data() << endl;
584
585 // Step 3: Convert `@i`-style references to `x[i]`
586 TPRegexp ordinalRegex("@([0-9]+)");
587 int nsub = 0;
588 do {
589 nsub = ordinalRegex.Substitute(formulaTString, "x[$1]");
590 } while (nsub > 0);
591
592 cxcoutD(InputArguments) << "Preprocessing formula step 3: replace '@'-references\n\t" << formulaTString.Data() << endl;
593
594 // Step 4: Replace all named references with "x[i]"-style
595 for (unsigned int i = 0; i < _origList.size(); ++i) {
596 const auto& var = _origList[i];
597 TString regex = "\\b";
598 regex += var.GetName();
599 regex += "\\b([^[]|$)"; //Negative lookahead. If the variable is called `x`, this might otherwise replace `x[0]`.
600 TPRegexp findParameterRegex(regex);
601
602 std::stringstream replacement;
603 replacement << "x[" << i << "]$1";
604 int nsub2 = 0;
605 do {
606 nsub2 = findParameterRegex.Substitute(formulaTString, replacement.str().c_str());
607 } while (nsub2 > 0);
608
609 cxcoutD(InputArguments) << "Preprocessing formula step 4: replace named references: "
610 << var.GetName() << " --> " << replacement.str()
611 << "\n\t" << formulaTString.Data() << endl;
612 }
613
614 cxcoutD(InputArguments) << "Final formula:\n\t" << formulaTString << endl;
615
616 return formulaTString.Data();
617}
618
619
620////////////////////////////////////////////////////////////////////////////////
621/// Analyse internal formula to find out which variables are actually in use.
623 RooArgList useList;
624 if (_tFormula == nullptr)
625 return useList;
626
627 const TString formulaTString = _tFormula->GetTitle();
628
629 std::set<unsigned int> matchedOrdinals;
630 TPRegexp newOrdinalRegex("\\bx\\[([0-9]+)\\]");
631 int offset = 0;
632 do {
633 std::unique_ptr<TObjArray> matches(newOrdinalRegex.MatchS(formulaTString, "", offset, 2));
634 if (matches->GetEntries() == 0)
635 break;
636
637 std::string fullMatch = static_cast<TObjString*>(matches->At(0))->GetString().Data();
638 std::string ordinal = static_cast<TObjString*>(matches->At(1))->GetString().Data();
639 offset = formulaTString.Index(newOrdinalRegex, offset) + fullMatch.size();
640
641 std::stringstream matchString(ordinal.c_str());
642 unsigned int i;
643 matchString >> i;
644
645 matchedOrdinals.insert(i);
646 } while (offset != -1);
647
648 for (unsigned int i : matchedOrdinals) {
649 useList.add(_origList[i]);
650 }
651
652 return useList;
653}
654
655
656////////////////////////////////////////////////////////////////////////////////
657/// From the internal representation, construct a formula by replacing all index place holders
658/// with the names of the variables that are being used to evaluate it.
659std::string RooFormula::reconstructFormula(std::string internalRepr) const {
660 TString internalReprT = internalRepr.c_str();
661
662 for (unsigned int i = 0; i < _origList.size(); ++i) {
663 const auto& var = _origList[i];
664 std::stringstream regexStr;
665 regexStr << "x\\[" << i << "\\]|@" << i;
666 TPRegexp regex(regexStr.str().c_str());
667
668 std::string replacement = std::string("[") + var.GetName() + "]";
669 regex.Substitute(internalReprT, replacement.c_str());
670 }
671
672 return internalReprT.Data();
673}
674#endif //GCC < 4.9 Check
#define e(i)
Definition RSha256.hxx:103
#define coutI(a)
#define cxcoutD(a)
#define coutF(a)
#define coutE(a)
#define ClassImp(name)
Definition Rtypes.h:364
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition TGX11.cxx:110
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 ...
virtual value_type getCurrentIndex() const
Return index number of current state.
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...
Definition RooAbsReal.h:61
virtual RooSpan< const double > getValues(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet=nullptr) const
by this change, please consult the release notes for ROOT 6.24 for guidance on how to make this trans...
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:21
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:29
RooCatType is an auxilary class for RooAbsCategory and defines a a single category state.
Int_t getVal() const
RooFormula internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition RooFormula.h:34
Bool_t reCompile(const char *newFormula)
Recompile formula with new expression.
virtual void printName(std::ostream &os) const
Print name of formula.
virtual void printTitle(std::ostream &os) const
Print title of formula.
virtual void printClassName(std::ostream &os) const
Print class name of formula.
RooArgSet actualDependents() const
Return list of arguments which are used in the formula.
Definition RooFormula.h:44
RooArgList usedVariables() const
Analyse internal formula to find out which variables are actually in use.
RooSpan< double > evaluateSpan(const RooAbsReal *dataOwner, RooBatchCompute::RunContext &inputData, const RooArgSet *nset=nullptr) const
virtual void printValue(std::ostream &os) const
Print value of formula.
RooFormula()
Default constructor coverity[UNINIT_CTOR].
Double_t eval(const RooArgSet *nset=0) const
Evalute all parameters/observables, and then evaluate formula.
void installFormulaOrThrow(const std::string &formulaa)
Check that the formula compiles, and also fulfills the assumptions.
void dump() const
DEBUG: Dump state information.
std::vector< bool > _isCategory
Original list of dependents.
Definition RooFormula.h:93
std::string processFormula(std::string origFormula) const
Process given formula by replacing all ordinal and name references by x[i], where i matches the posit...
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Printing interface.
virtual void printArgs(std::ostream &os) const
Print arguments of formula, i.e. dependents that are actually used.
std::string reconstructFormula(std::string internalRepr) const
From the internal representation, construct a formula by replacing all index place holders with the n...
RooArgList _origList
Definition RooFormula.h:92
Bool_t changeDependents(const RooAbsCollection &newDeps, Bool_t mustReplaceAll, Bool_t nameChange)
Change used variables to those with the same name in given list.
std::unique_ptr< TFormula > _tFormula
Whether an element of the _origList is a category.
Definition RooFormula.h:94
RooPlotable is a 'mix-in' base class that define the standard RooFit plotting and printing methods.
A simple container to hold a batch of data values.
Definition RooSpan.h:34
The Formula class.
Definition TFormula.h:87
void SetName(const char *name)
Set the name of the formula.
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
Collectable string class.
Definition TObjString.h:28
Basic string class.
Definition TString.h:136
Ssiz_t Length() const
Definition TString.h:410
const char * Data() const
Definition TString.h:369
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:692
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:615
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:639
static const char * what
Definition stlLoader.cc:6
This struct enables passing computation data around between elements of a computation graph.
Definition RunContext.h:31
RooSpan< double > makeBatch(const RooAbsReal *owner, std::size_t size)
Create a writable batch.
static void output(int code)
Definition gifencode.c:226