eic-smear  1.0.3
A collection of ROOT classes for Monte Carlo events and a fast-smearing code simulating detector effects for the Electron-Ion Collider task force
FormulaString.cxx
Go to the documentation of this file.
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 
102 std::string FormulaString::Parse(const std::string& formula) {
103  using std::string;
104  using std::vector;
105  mVariables.clear();
106  // Get all the patterns that appear in the input string
107  // We want to preserve the order in which the arguments appear
108  // so store the position of each argument with its name.
109  std::map<int, string> args;
110  typedef vector<string>::const_iterator StrIter;
111  for (StrIter i = patterns().begin(); i != patterns().end(); ++i) {
112  size_t position = formula.find(*i);
113  if (position != string::npos) {
114  args.insert(std::make_pair(position, *i));
115  } // if
116  } // for
117  // Substitute each pattern (E, P etc) with
118  // variables recognised by ROOT::TFormula (x, y, z, t)
119  // Also, accumulate the Smear::KinType corresponding to each pattern
120  // in the vector function argument.
121  std::list<string> substitutions(tformulaVariables,
122  tformulaVariables + 4);
123  TString s(formula);
124  for (std::map<int, string>::const_iterator i = args.begin();
125  i != args.end(); ++i) {
126  s.ReplaceAll(i->second, substitutions.front());
127  substitutions.pop_front();
128  mVariables.push_back(GetKinType(i->second));
129  } // for
130  return string(s.Data());
131 }
132 
133 std::string FormulaString::GetString() const {
134  std::string str;
135  if (mFormula) {
136  str = mFormula->GetTitle();
137  } // if
138  return str;
139 }
140 
141 std::string FormulaString::GetInputString() const {
142  return mInput;
143 }
144 
145 KinType FormulaString::GetKinType(const std::string& name) {
146  KinType type(kInvalidKinType);
147  if (kinTypeTable().find(name) != kinTypeTable().end()) {
148  type = kinTypes[name];
149  } // if
150  return type;
151 }
152 
153 std::string FormulaString::GetKinName(KinType type) {
154  std::string name;
155  std::map<std::string, KinType>::const_iterator i;
156  for (i = kinTypeTable().begin(); i != kinTypeTable().end(); ++i) {
157  if (i->second == type) {
158  name = i->first;
159  } // if
160  } // for
161  return name;
162 }
163 
164 } // namespace Smear
static std::string GetKinName(KinType)
virtual std::string GetString() const
static KinType GetKinType(const std::string &)
virtual double Eval(const std::vector< double > &) const
virtual std::string GetInputString() const
std::string Parse(const std::string &)
virtual std::vector< Smear::KinType > Variables() const
std::string mInput
Original formula (before parsing)