Skip to content

Commit 3f41e4c

Browse files
authored
[RF] Allow scientific notation in JSONfactory formula
Fixes #14637
1 parent 28582e0 commit 3f41e4c

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

hist/hist/inc/TFormula.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ class TFormula : public TNamed
156156
static Bool_t IsOperator(const char c);
157157
static Bool_t IsBracket(const char c);
158158
static Bool_t IsFunctionNameChar(const char c);
159-
static Bool_t IsScientificNotation(const TString & formula, int ipos);
160159
static Bool_t IsHexadecimal(const TString & formula, int ipos);
161160
static Bool_t IsAParameterName(const TString & formula, int ipos);
162161
void ExtractFunctors(TString &formula);
@@ -238,6 +237,8 @@ class TFormula : public TNamed
238237
return fHessFuncPtr != nullptr;
239238
}
240239

240+
static Bool_t IsScientificNotation(const TString & formula, int ipos);
241+
241242
// template <class T>
242243
// T Eval(T x, T y = 0, T z = 0, T t = 0) const;
243244
template <class T>

roofit/hs3/src/JSONFactories_RooFitCore.cxx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,24 @@ namespace {
6565
* arguments are returned as a vector of strings.
6666
*
6767
* @param expr A string representing a mathematical expression.
68-
* @return A vector of strings representing the extracted arguments.
68+
* @return A set of unique strings representing the extracted arguments.
6969
*/
70-
std::vector<std::string> extractArguments(std::string expr)
70+
std::set<std::string> extractArguments(std::string expr)
7171
{
7272
// Get rid of whitespaces
7373
expr.erase(std::remove_if(expr.begin(), expr.end(), [](unsigned char c) { return std::isspace(c); }), expr.end());
7474

75-
std::vector<std::string> arguments;
75+
std::set<std::string> arguments;
7676
size_t startidx = expr.size();
7777
for (size_t i = 0; i < expr.size(); ++i) {
7878
if (startidx >= expr.size()) {
7979
if (isalpha(expr[i])) {
8080
startidx = i;
81+
// check this character is not part of scientific notation, e.g. 2e-5
82+
if (TFormula::IsScientificNotation(expr, i)) {
83+
// if it is, we ignore this character
84+
startidx = expr.size();
85+
}
8186
}
8287
} else {
8388
if (!isdigit(expr[i]) && !isalpha(expr[i]) && expr[i] != '_') {
@@ -87,12 +92,12 @@ std::vector<std::string> extractArguments(std::string expr)
8792
}
8893
std::string arg(expr.substr(startidx, i - startidx));
8994
startidx = expr.size();
90-
arguments.push_back(arg);
95+
arguments.insert(arg);
9196
}
9297
}
9398
}
9499
if (startidx < expr.size()) {
95-
arguments.push_back(expr.substr(startidx));
100+
arguments.insert(expr.substr(startidx));
96101
}
97102
return arguments;
98103
}

roofit/hs3/test/testRooFitHS3.cxx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <RooRealVar.h>
2424
#include <RooSimultaneous.h>
2525
#include <RooWorkspace.h>
26+
#include <RooFormulaVar.h>
2627

2728
#include <TROOT.h>
2829

@@ -404,3 +405,35 @@ TEST(RooFitHS3, SimultaneousGaussians)
404405
int status = validate(simPdf);
405406
EXPECT_EQ(status, 0);
406407
}
408+
409+
// https://github.com/root-project/root/issues/14637
410+
TEST(RooFitHS3, ScientificNotation)
411+
{
412+
RooRealVar v1("v1","v1",1.0);
413+
RooRealVar v2("v2","v2",1.0);
414+
415+
// make a formula that is some parameters times some numbers
416+
auto thestring = "@0*0.2e-6 + @1*0.1";
417+
RooArgList arglist;
418+
arglist.add(v1);
419+
arglist.add(v2);
420+
421+
RooFormulaVar fvBad("fvBad", "fvBad", thestring, arglist);
422+
423+
// make gaussian with mean as that formula
424+
RooRealVar x("x","x",0.0,-5.0,5.0);
425+
RooGaussian g("g","g",x, fvBad, 1.0);
426+
427+
RooWorkspace ws("ws");
428+
ws.import(g);
429+
//std::cout << (fvBad.expression()) << std::endl;
430+
431+
// export to json
432+
RooJSONFactoryWSTool t(ws);
433+
auto jsonStr = t.exportJSONtoString();
434+
435+
// try to import, before the fix, it threw RooJSONFactoryWSTool::DependencyMissingError because of problem reading the exponential char
436+
RooWorkspace newws("newws");
437+
RooJSONFactoryWSTool t2(newws);
438+
ASSERT_TRUE(t2.importJSONfromString(jsonStr));
439+
}

0 commit comments

Comments
 (0)