ATLAS Offline Software
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 
15 using 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 
33 bool 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 
46  return true;
47 }
48 bool 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+"_";
59  }
60  return true;
61 }
62 
63 bool 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 
71 {
72 
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 
95 double 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 
150 bool 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 
172 bool 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 
188  return true;
189 }
190 
191 double ExpressionEvaluator::Eval( const std::string& expr )
192 {
193  return Eval( expr.c_str() );
194 }
195 
196 double ExpressionEvaluator::Eval( const char* expr_mod )
197 {
198 
199  std::string expr = expr_mod;
200  std::string::size_type start_index = 0;
201  std::string::size_type end_index = 0;
202  while(true)
203  {
204  start_index = expr.find('[', start_index);
205  if(start_index == std::string::npos) break;
206  std::string::size_type boundary_index = expr.find(']', start_index);
207  expr.replace(start_index,1,1,'_');
208  end_index = expr.find(',', start_index);
209  if(end_index != std::string::npos && end_index < boundary_index)
210  {
211  start_index++;
212  std::string var1 = expr.substr(start_index, end_index-start_index);
213  double eval1 = EvaluateString( var1 );
214  std::stringstream ss1;
215  std::string str1;
216  ss1 << eval1;
217  ss1 >> str1;
218  expr.replace(start_index, end_index-start_index, str1, 0, str1.size());
219  }
220  else
221  {
222  end_index = boundary_index;
223  if(end_index != std::string::npos)
224  {
225  start_index++;
226  std::string var1 = expr.substr(start_index, end_index-start_index);
227  double eval1 = EvaluateString( var1 );
228  std::stringstream ss1;
229  std::string str1;
230  ss1 << eval1;
231  ss1 >> str1;
232  expr.replace(start_index, end_index-start_index, str1, 0, str1.size());
233  }
234  }
235  }
236  start_index = 0;
237  end_index = 0;
238  while(true)
239  {
240  start_index = expr.find(',', start_index);
241  if(start_index == std::string::npos) break;
242  expr.replace(start_index,1,1,'_');
243  end_index = expr.find(']', start_index);
244  start_index++;
245  std::string var2 = expr.substr(start_index, end_index-start_index);
246  double eval2 = EvaluateString( var2 );
247  std::stringstream ss2;
248  std::string str2;
249  ss2 << eval2;
250  ss2 >> str2;
251  expr.replace(start_index, end_index-start_index, str2, 0, str2.size());
252  }
253  start_index = 0;
254  end_index = 0;
255  while(true)
256  {
257  start_index = expr.find(']', start_index);
258  if(start_index == std::string::npos) break;
259  expr.replace(start_index,1,1,'_');
260  }
261  double result = EvaluateString( expr );
262  if( m_calc.status() != HepTool::Evaluator::OK )
263  {
264  std::cerr << expr << std::endl;
265  for (int i=0; i<m_calc.error_position(); i++)
266  {
267  std::cerr << "-";
268  }
269  std::cerr << "^\a" << std::endl;
270  m_calc.print_error();
271  std::cerr << std::endl;
272  }
273  return result;
274 }
275 
276 std::string ExpressionEvaluator::trim (const std::string& s)
277 //-------------------------------------------------------------
278 {
279  if (s.size () == 0) return (s);
280  std::string temp = s;
281  std::string::size_type i;
282  i = temp.find_first_not_of (' ');
283  if (i == std::string::npos) return std::string();
284 // There is at least 1 non blank character in s.
285  if (i > 0)
286  {
287  temp = temp.substr (i);
288  }
289  i = temp.find_last_not_of (' ');
290  if (i < temp.size ())
291  {
292  temp.resize (i + 1);
293  }
294  return (temp);
295 }
296 
297 std::vector<std::string> ExpressionEvaluator::tokenize(const std::string& sep,const std::string& expr)
298 {
299  std::vector<std::string> tempvect;
300  AGDDTokenizer aa(sep,expr);
301  for (unsigned int i=0;i<aa.size();i++) tempvect.push_back(trim(aa[i]));
302  return tempvect;
303 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
temp
Definition: JetEventDict.h:21
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
get_generator_info.result
result
Definition: get_generator_info.py:21
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
AGDD::ExpressionEvaluator::trim
static std::string trim(const std::string &)
Definition: ExpressionEvaluator.cxx:276
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
CheckAppliedSFs.var_name
var_name
Definition: CheckAppliedSFs.py:241
index
Definition: index.py:1
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
AGDD::ExpressionEvaluator::ExpressionEvaluator
ExpressionEvaluator()
Definition: ExpressionEvaluator.cxx:17
athena.value
value
Definition: athena.py:122
AGDD::ExpressionEvaluator::is_real_variable
bool is_real_variable(const std::string &var_name)
Definition: ExpressionEvaluator.cxx:70
AGDD
Definition: ExpressionEvaluator.h:14
AGDD::ExpressionEvaluator::m_calc
HepTool::Evaluator m_calc
Definition: ExpressionEvaluator.h:47
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
AGDD::ExpressionEvaluator::RegisterConstant
bool RegisterConstant(std::string &c, double v)
Definition: ExpressionEvaluator.cxx:33
AGDD::ExpressionEvaluator::RegisterArray
bool RegisterArray(std::string &c, const std::vector< double > &v)
Definition: ExpressionEvaluator.cxx:48
AGDD::ExpressionEvaluator::m_PCTable
PhysicalConstantsTable m_PCTable
Definition: ExpressionEvaluator.h:49
AGDD::ExpressionEvaluator::m_real_vars
std::vector< std::string > m_real_vars
Definition: ExpressionEvaluator.h:51
lumiFormat.i
int i
Definition: lumiFormat.py:92
AGDD::ExpressionEvaluator::~ExpressionEvaluator
~ExpressionEvaluator()
Definition: ExpressionEvaluator.cxx:26
AGDD::ExpressionEvaluator::RegisterVariable
bool RegisterVariable(const std::string &var_name, double value)
Definition: ExpressionEvaluator.cxx:63
AGDDTokenizer.h
python.selection.variable
variable
Definition: selection.py:33
AGDD::ExpressionEvaluator::m_fileCurrentlyParsed
std::string m_fileCurrentlyParsed
Definition: ExpressionEvaluator.h:50
AGDD::ExpressionEvaluator::m_CTable
ConstantsTable m_CTable
Definition: ExpressionEvaluator.h:48
grepfile.sep
sep
Definition: grepfile.py:38
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
AGDD::ExpressionEvaluator::tokenize
static std::vector< std::string > tokenize(const std::string &, const std::string &)
Definition: ExpressionEvaluator.cxx:297
AGDD::ExpressionEvaluator::RegisterExpression
bool RegisterExpression(std::string &c, const std::string &v)
Definition: ExpressionEvaluator.cxx:172
ExpressionEvaluator.h
python.PyAthena.v
v
Definition: PyAthena.py:157
AGDD::ExpressionEvaluator::is_delimiter
bool is_delimiter(char c)
Definition: ExpressionEvaluator.cxx:89
AGDD::ExpressionEvaluator::EvaluateString
double EvaluateString(const std::string &str)
Definition: ExpressionEvaluator.cxx:95
DeMoScan.index
string index
Definition: DeMoScan.py:362
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
AGDDTokenizer
Definition: AGDDTokenizer.h:10
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
AGDD::ExpressionEvaluator::Eval
double Eval(const std::string &expr)
Definition: ExpressionEvaluator.cxx:191
unit
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
Definition: AmgMatrixBasePlugin.h:20
AGDD::ExpressionEvaluator::RegisterPhysConstant
bool RegisterPhysConstant(std::string &, const std::string &, const std::string &)
Definition: ExpressionEvaluator.cxx:150
makeTransCanvas.text
text
Definition: makeTransCanvas.py:11
str
Definition: BTagTrackIpAccessor.cxx:11
test_AnalysisBaseEventLoopJob.aa
aa
Definition: test_AnalysisBaseEventLoopJob.py:37
python.compressB64.c
def c
Definition: compressB64.py:93