EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FormulaString.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FormulaString.cxx
1 
11 
12 #include <algorithm>
13 #include <iterator>
14 #include <list>
15 #include <map>
16 #include <string>
17 #include <vector>
18 
19 #include <TFormula.h>
20 #include <TString.h>
21 #include <TUUID.h>
22 
23 namespace {
24 
25 // Valid patterns for the names of smearing function variables.
26 // These are replaced with "x", "y", "z", "t" when the functions are parsed.
27 std::vector<std::string> functionPatterns;
28 
29 // Returns a reference to the function pattern vector, filling
30 // it first if needed.
31 const std::vector<std::string>& patterns() {
32  if (functionPatterns.empty()) {
33  const std::string array[6] = {"E", "P", "theta", "phi", "pT", "pZ"};
34  functionPatterns.assign(array, array + 6);
35  } // if
36  return functionPatterns;
37 }
38 
39 // Variables recognised by ROOT::TFormula.
40 // These replace the functionPatterns above so ROOT::TFormula can
41 // understand the formula string.
42 const std::string tformulaVariables[4] = {"x", "y", "z", "t"};
43 
44 // KinType keyed by corresponding string name.
45 std::map<std::string, Smear::KinType> kinTypes;
46 
47 // Returns a reference to the KinType table, populating it first if needed.
48 const std::map<std::string, Smear::KinType>& kinTypeTable() {
49  if (kinTypes.empty()) {
50  kinTypes.insert(std::make_pair("E", Smear::kE));
51  kinTypes.insert(std::make_pair("P", Smear::kP));
52  kinTypes.insert(std::make_pair("theta", Smear::kTheta));
53  kinTypes.insert(std::make_pair("phi", Smear::kPhi));
54  kinTypes.insert(std::make_pair("pT", Smear::kPt));
55  kinTypes.insert(std::make_pair("pZ", Smear::kPz));
56  } // if
57  return kinTypes;
58 }
59 
60 } // anonymous namespace
61 
62 namespace Smear {
63 
64 // This is basically a wrapper around ROOT::TFormula, with functionality
65 // to parse functions containing "P", "theta" etc into "x, y, z, t"
66 // as accepted by TFormula.
67 
69  if (mFormula) {
70  delete mFormula;
71  mFormula = NULL;
72  } // if
73 }
74 
76 : mFormula(NULL) {
77 }
78 
79 FormulaString::FormulaString(const std::string& formula)
80 : mFormula(NULL)
81 , mInput(formula) {
82  std::string f = Parse(formula);
83  mFormula = new TFormula(TUUID().AsString(), f.c_str());
84 }
85 
86 double FormulaString::Eval(const std::vector<double>& args) const {
87  if (args.size() != mVariables.size()) {
88  std::cerr << "FormulaString::Eval() got " << args.size() <<
89  " arguments, expected " << mVariables.size() << std::endl;
90  } // if
91  // TFormula accepts up to four arguments.
92  // Use default zeros for absent arguments.
93  std::vector<double> a(args);
94  a.resize(4, 0.);
95  return mFormula->Eval(a.at(0), a.at(1), a.at(2), a.at(3));
96 }
97 
98 std::vector<KinType> FormulaString::Variables() const {
99  return mVariables;
100 }
101 
104 std::string FormulaString::Parse(const std::string& formula) {
105  using std::string;
106  using std::vector;
107  mVariables.clear();
108  // Get all the patterns that appear in the input string
109  // We want to preserve the order in which the arguments appear
110  // so store the position of each argument with its name.
111  std::map<int, string> args;
112  typedef vector<string>::const_iterator StrIter;
113  for (StrIter i = patterns().begin(); i != patterns().end(); ++i) {
114  size_t position = formula.find(*i);
115  if (position != string::npos) {
116  args.insert(std::make_pair(position, *i));
117  } // if
118  } // for
119  // Substitute each pattern (E, P etc) with
120  // variables recognised by ROOT::TFormula (x, y, z, t)
121  // Also, accumulate the Smear::KinType corresponding to each pattern
122  // in the vector function argument.
123  std::list<string> substitutions(tformulaVariables,
124  tformulaVariables + 4);
125  TString s(formula);
126  for (std::map<int, string>::const_iterator i = args.begin();
127  i != args.end(); ++i) {
128  s.ReplaceAll(i->second, substitutions.front());
129  substitutions.pop_front();
130  mVariables.push_back(GetKinType(i->second));
131  } // for
132  return string(s.Data());
133 }
134 
135 std::string FormulaString::GetString() const {
136  std::string str;
137  if (mFormula) {
138  str = mFormula->GetTitle();
139  } // if
140  return str;
141 }
142 
143 std::string FormulaString::GetInputString() const {
144  return mInput;
145 }
146 
148  KinType type(kInvalidKinType);
149  if (kinTypeTable().find(name) != kinTypeTable().end()) {
150  type = kinTypes[name];
151  } // if
152  return type;
153 }
154 
156  std::string name;
157  std::map<std::string, KinType>::const_iterator i;
158  for (i = kinTypeTable().begin(); i != kinTypeTable().end(); ++i) {
159  if (i->second == type) {
160  name = i->first;
161  } // if
162  } // for
163  return name;
164 }
165 
166 } // namespace Smear