ATLAS Offline Software
Loading...
Searching...
No Matches
ExpressionEvaluator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#include <cstdlib>
9#include <cctype>
10#include <cstring>
11#include <iostream>
12#include <sstream>
13#include <algorithm>
14
15using namespace AGDD;
16
18{
19 m_calc.clear();
20 m_calc.setStdMath(); // set standard constants and functions
21 // Set Geant4 system of units
22 m_calc.setSystemOfUnits(1.e+3, 1./1.60217733e-25, 1.e+9, 1./1.60217733e-10,1.0, 1.0, 1.0);
24}
25
27{
28 m_CTable.clear();
29 m_PCTable.clear();
30 m_calc.clear();
31}
32
33bool ExpressionEvaluator::RegisterConstant( std::string& c, double v )
34{
35 double value = v;
36
37 if( m_calc.status() != HepTool::Evaluator::OK )
38 {
39 std::cerr << "Expression evaluator:: Error registering constant " << c << std::endl;
40 m_calc.print_error();
41 std::cout << std::endl;
42 return false;
43 }
44
45 RegisterVariable( c, value );
46 return true;
47}
48bool ExpressionEvaluator::RegisterArray( std::string& c, const std::vector<double>& v)
49{
50 for(unsigned int i=0; i<v.size(); i++)
51 {
52 double value = v[i];
53 std::stringstream ss;
54 std::string index;
55 ss << i;
56 ss >> index;
57 std::string name = c+"_"+index+"_";
58 RegisterVariable( name, value );
59 }
60 return true;
61}
62
63bool ExpressionEvaluator::RegisterVariable( const std::string& var_name, double value)
64{
65 m_real_vars.push_back(var_name);
66 m_calc.setVariable( var_name.c_str(), value );
67 return true;
68}
69
70bool ExpressionEvaluator::is_real_variable(const std::string& var_name)
71{
72
73 std::vector<std::string>::iterator start = m_real_vars.begin();
74 std::vector<std::string>::iterator end = m_real_vars.end();
75 std::vector<std::string>::iterator iter;
76
77 iter = find(start, end, var_name);
78
79 if (iter == end)
80 {
81 return false;
82 }
83 else
84 {
85 return true;
86 }
87}
88
90{
91 if(strchr(" ()|&=!><+-%*/^", c) || c==9 || c==0 || c=='\r' || c=='\n' || c=='\t' || c=='\0' || isspace(c)) return true;
92 else return false;
93}
94
95double ExpressionEvaluator::EvaluateString(const std::string& str)
96{
97 std::string str_mod = str;
98 const char* c_str_mod = str.c_str(); //string to be modified with file namespace!
99 std::vector<int> variable_ends; //variable names to be changed
100 int cur_variable_end = 0;
101 while(*c_str_mod)
102 {
103 if(is_delimiter(*c_str_mod) || isdigit(*c_str_mod))
104 {
105 c_str_mod++;
106 cur_variable_end++;
107 }
108 else if(isalpha(*c_str_mod))
109 {
110 char variable[80];
111 char* token;
112 token = variable;
113 *token = '\0';
114 while(!is_delimiter(*c_str_mod))
115 {
116 *token=*c_str_mod;
117 token++;
118 c_str_mod++;
119 cur_variable_end++;
120 }
121 *token = '\0';
122 std::string variable_to_check = variable;
123 if(is_real_variable(variable_to_check))
124 {
125 variable_ends.push_back(cur_variable_end);
126 }
127 }
128 else
129 {
130 c_str_mod++;
131 cur_variable_end++;
132 }
133 std::string::size_type shift = 0;
134 std::string::size_type ns_length = m_fileCurrentlyParsed.size();
135 for(unsigned int i=0; i<variable_ends.size(); i++)
136 {
137 str_mod.insert(shift+variable_ends[i],m_fileCurrentlyParsed);
138 shift += ns_length;
139 }
140 }
141 double result = m_calc.evaluate( str_mod.c_str() );
142 return result;
143}
144/*********************************************************************************************************/
145/*********************************************************************************************************/
146/*********************************************************************************************************/
147/*********************************************************************************************************/
148
149
150bool ExpressionEvaluator::RegisterPhysConstant( std::string& c, const std::string& value, const std::string& unit )
151{
152 std::string expr = value;
153 expr += "*(";
154 expr += unit;
155 expr += ")";
156
157 double dvalue = EvaluateString( expr );
158
159 if( m_calc.status() != HepTool::Evaluator::OK )
160 {
161 std::cerr << "Expression evaluator:: Error registering quantity "
162 << c << std::endl;
163 m_calc.print_error();
164 std::cout << std::endl;
165 return false;
166 }
167
168 RegisterVariable( c, dvalue );
169 return true;
170}
171
172bool ExpressionEvaluator::RegisterExpression( std::string& name, const std::string& text )
173{
174 std::string expr = "(";
175 expr += text;
176 expr += ")";
177 double value = EvaluateString( expr );
178
179 if( m_calc.status() != HepTool::Evaluator::OK )
180 {
181 std::cerr << "Expression evaluator:: Error registering expression " << name << std::endl;
182 m_calc.print_error();
183 std::cout << std::endl;
184 return false;
185 }
186
187 RegisterVariable( name, value );
188 return true;
189}
190
191
192double ExpressionEvaluator::Eval( std::string_view expr_mod )
193{
194
195 std::string expr {expr_mod};
196 std::string::size_type start_index = 0;
197 std::string::size_type end_index = 0;
198 while(true)
199 {
200 start_index = expr.find('[', start_index);
201 if(start_index == std::string::npos) break;
202 std::string::size_type boundary_index = expr.find(']', start_index);
203 expr.replace(start_index,1,1,'_');
204 end_index = expr.find(',', start_index);
205 if(end_index != std::string::npos && end_index < boundary_index)
206 {
207 start_index++;
208 std::string var1 = expr.substr(start_index, end_index-start_index);
209 double eval1 = EvaluateString( var1 );
210 std::stringstream ss1;
211 std::string str1;
212 ss1 << eval1;
213 ss1 >> str1;
214 expr.replace(start_index, end_index-start_index, str1, 0, str1.size());
215 }
216 else
217 {
218 end_index = boundary_index;
219 if(end_index != std::string::npos)
220 {
221 start_index++;
222 std::string var1 = expr.substr(start_index, end_index-start_index);
223 double eval1 = EvaluateString( var1 );
224 std::stringstream ss1;
225 std::string str1;
226 ss1 << eval1;
227 ss1 >> str1;
228 expr.replace(start_index, end_index-start_index, str1, 0, str1.size());
229 }
230 }
231 }
232 start_index = 0;
233 end_index = 0;
234 while(true)
235 {
236 start_index = expr.find(',', start_index);
237 if(start_index == std::string::npos) break;
238 expr.replace(start_index,1,1,'_');
239 end_index = expr.find(']', start_index);
240 start_index++;
241 std::string var2 = expr.substr(start_index, end_index-start_index);
242 double eval2 = EvaluateString( var2 );
243 std::stringstream ss2;
244 std::string str2;
245 ss2 << eval2;
246 ss2 >> str2;
247 expr.replace(start_index, end_index-start_index, str2, 0, str2.size());
248 }
249 start_index = 0;
250 end_index = 0;
251 while(true)
252 {
253 start_index = expr.find(']', start_index);
254 if(start_index == std::string::npos) break;
255 expr.replace(start_index,1,1,'_');
256 }
257 double result = EvaluateString( expr );
258 if( m_calc.status() != HepTool::Evaluator::OK )
259 {
260 std::cerr << expr << std::endl;
261 for (int i=0; i<m_calc.error_position(); i++)
262 {
263 std::cerr << "-";
264 }
265 std::cerr << "^\a" << std::endl;
266 m_calc.print_error();
267 std::cerr << std::endl;
268 }
269 return result;
270}
271
272std::string ExpressionEvaluator::trim (const std::string& s)
273//-------------------------------------------------------------
274{
275 if (s.size () == 0) return (s);
276 std::string temp = s;
277 std::string::size_type i;
278 i = temp.find_first_not_of (' ');
279 if (i == std::string::npos) return std::string();
280// There is at least 1 non blank character in s.
281 if (i > 0)
282 {
283 temp = temp.substr (i);
284 }
285 i = temp.find_last_not_of (' ');
286 if (i < temp.size ())
287 {
288 temp.resize (i + 1);
289 }
290 return (temp);
291}
292
293std::vector<std::string> ExpressionEvaluator::tokenize(const std::string& sep,const std::string& expr)
294{
295 std::vector<std::string> tempvect;
296 AGDDTokenizer aa(sep,expr);
297 for (unsigned int i=0;i<aa.size();i++) tempvect.push_back(trim(aa[i]));
298 return tempvect;
299}
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
static Double_t ss
double EvaluateString(const std::string &str)
std::vector< std::string > m_real_vars
PhysicalConstantsTable m_PCTable
static std::vector< std::string > tokenize(const std::string &, const std::string &)
bool is_real_variable(const std::string &var_name)
bool RegisterVariable(const std::string &var_name, double value)
static std::string trim(const std::string &)
bool RegisterPhysConstant(std::string &, const std::string &, const std::string &)
bool RegisterArray(std::string &c, const std::vector< double > &v)
double Eval(std::string_view expr)
bool RegisterConstant(std::string &c, double v)
bool RegisterExpression(std::string &c, const std::string &v)
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140
Definition index.py:1