Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // G4GDMLEvaluator implementation 27 // 28 // Author: Zoltan Torzsok, November 2007 29 // -------------------------------------------------------------------- 30 31 #include <sstream> 32 33 #include "G4GDMLEvaluator.hh" 34 #include "G4SystemOfUnits.hh" 35 36 // -------------------------------------------------------------------- 37 G4GDMLEvaluator::G4GDMLEvaluator() 38 { 39 eval.clear(); 40 eval.setStdMath(); 41 eval.setSystemOfUnits(meter, kilogram, second, ampere, kelvin, mole, candela); 42 } 43 44 // -------------------------------------------------------------------- 45 void G4GDMLEvaluator::Clear() 46 { 47 eval.clear(); 48 eval.setStdMath(); 49 eval.setSystemOfUnits(meter, kilogram, second, ampere, kelvin, mole, candela); 50 51 variableList.clear(); 52 } 53 54 // -------------------------------------------------------------------- 55 void G4GDMLEvaluator::DefineConstant(const G4String& name, G4double value) 56 { 57 if(eval.findVariable(name)) 58 { 59 G4String error_msg = "Redefinition of constant or variable: " + name; 60 G4Exception("G4GDMLEvaluator::DefineConstant()", "InvalidExpression", 61 FatalException, error_msg); 62 } 63 eval.setVariable(name.c_str(), value); 64 } 65 66 // -------------------------------------------------------------------- 67 void G4GDMLEvaluator::DefineVariable(const G4String& name, G4double value) 68 { 69 if(eval.findVariable(name)) 70 { 71 G4String error_msg = "Redefinition of constant or variable: " + name; 72 G4Exception("G4GDMLEvaluator::DefineVariable()", "InvalidExpression", 73 FatalException, error_msg); 74 } 75 eval.setVariable(name.c_str(), value); 76 variableList.push_back(name); 77 } 78 79 // -------------------------------------------------------------------- 80 void G4GDMLEvaluator::DefineMatrix(const G4String& name, G4int coldim, 81 std::vector<G4double> valueList) 82 { 83 const G4int size = (G4int)valueList.size(); 84 85 if(size == 0) 86 { 87 G4String error_msg = "Matrix '" + name + "' is empty!"; 88 G4Exception("G4GDMLEvaluator::DefineMatrix()", "InvalidSize", 89 FatalException, error_msg); 90 } 91 /* 92 if (size == 1) 93 { 94 G4String error_msg = "Matrix '" + name 95 + "' has only one element! " 96 + "Define a constant instead!!"; 97 G4Exception("G4GDMLEvaluator::DefineMatrix()", "InvalidSize", 98 FatalException, error_msg); 99 } 100 */ 101 102 if(size % coldim != 0) 103 { 104 G4String error_msg = "Matrix '" + name + "' is not filled correctly!"; 105 G4Exception("G4GDMLEvaluator::DefineMatrix()", "InvalidSize", 106 FatalException, error_msg); 107 } 108 109 if((size == coldim) || (coldim == 1)) // Row- or column matrix 110 { 111 for(G4int i = 0; i < size; ++i) 112 { 113 std::stringstream MatrixElementNameStream; 114 MatrixElementNameStream << name << "_" << i; 115 DefineConstant(MatrixElementNameStream.str(), valueList[i]); 116 } 117 } 118 else // Normal matrix 119 { 120 const G4int rowdim = size / coldim; 121 122 for(G4int i = 0; i < rowdim; ++i) 123 { 124 for(G4int j = 0; j < coldim; ++j) 125 { 126 std::stringstream MatrixElementNameStream; 127 MatrixElementNameStream << name << "_" << i << "_" << j; 128 DefineConstant(MatrixElementNameStream.str(), 129 valueList[coldim * i + j]); 130 } 131 } 132 } 133 } 134 135 // -------------------------------------------------------------------- 136 void G4GDMLEvaluator::SetVariable(const G4String& name, G4double value) 137 { 138 if(!IsVariable(name)) 139 { 140 G4String error_msg = "Variable '" + name + "' is not defined!"; 141 G4Exception("G4GDMLEvaluator::SetVariable()", "InvalidSetup", 142 FatalException, error_msg); 143 } 144 eval.setVariable(name.c_str(), value); 145 } 146 147 // -------------------------------------------------------------------- 148 G4bool G4GDMLEvaluator::IsVariable(const G4String& name) const 149 { 150 const std::size_t variableCount = variableList.size(); 151 152 for(std::size_t i = 0; i < variableCount; ++i) 153 { 154 if(variableList[i] == name) 155 { 156 return true; 157 } 158 } 159 160 return false; 161 } 162 163 // -------------------------------------------------------------------- 164 G4String G4GDMLEvaluator::SolveBrackets(const G4String& in) 165 { 166 std::string::size_type full = in.size(); 167 std::string::size_type open = in.find("[", 0); 168 std::string::size_type close = in.find("]", 0); 169 170 if(open == close) 171 { 172 return in; 173 } 174 175 if((open > close) || (open == std::string::npos) || 176 (close == std::string::npos)) 177 { 178 G4String error_msg = "Bracket mismatch: " + in; 179 G4Exception("G4GDMLEvaluator::SolveBrackets()", "InvalidExpression", 180 FatalException, error_msg); 181 return in; 182 } 183 184 std::string::size_type begin = open; 185 std::string::size_type end = 0; 186 std::string::size_type end1 = 0; 187 std::string out; 188 out.append(in, 0, open); 189 190 do // Loop for all possible matrix elements in 'in' 191 { 192 do // SolveBrackets for one matrix element 193 { 194 end = in.find(",", begin + 1); 195 end1 = in.find("]", begin + 1); 196 if(end > end1) 197 { 198 end = end1; 199 } 200 if(end == std::string::npos) 201 { 202 end = close; 203 } 204 205 std::stringstream indexStream; 206 indexStream << "_" 207 << EvaluateInteger(in.substr(begin + 1, end - begin - 1)) - 1; 208 209 out.append(indexStream.str()); 210 211 begin = end; 212 213 } while(end < close); 214 215 if(full == close) 216 { 217 return out; 218 } 219 220 open = in.find("[", begin); 221 close = in.find("]", begin + 1); 222 223 if(open == close) 224 { 225 out.append(in.substr(end + 1, full - end - 1)); 226 return out; 227 } 228 out.append(in.substr(end + 1, open - end - 1)); 229 230 begin = open; 231 232 } while(close < full); 233 234 return out; 235 } 236 237 // -------------------------------------------------------------------- 238 G4double G4GDMLEvaluator::Evaluate(const G4String& in) 239 { 240 G4String expression = SolveBrackets(in); 241 242 G4double value = 0.0; 243 244 if(!expression.empty()) 245 { 246 value = eval.evaluate(expression.c_str()); 247 248 if(eval.status() != G4Evaluator::OK) 249 { 250 eval.print_error(); 251 G4String error_msg = "Error in expression: " + expression; 252 G4Exception("G4GDMLEvaluator::Evaluate()", "InvalidExpression", 253 FatalException, error_msg); 254 } 255 } 256 return value; 257 } 258 259 // -------------------------------------------------------------------- 260 G4int G4GDMLEvaluator::EvaluateInteger(const G4String& expression) 261 { 262 // This function is for evaluating integer expressions, 263 // like loop variables and matrix indices. 264 // Complains if the evaluated expression has a fractional 265 // part different from zero 266 267 G4double value = Evaluate(expression); 268 269 G4int whole = (G4int) value; 270 G4double frac = value - (G4double) whole; 271 272 if(frac != 0.0) 273 { 274 G4String error_msg = 275 "Expression '" + expression + "' is expected to have an integer value!"; 276 G4Exception("G4GDMLEvaluator::EvaluateInteger()", "InvalidExpression", 277 FatalException, error_msg); 278 } 279 return whole; 280 } 281 282 // -------------------------------------------------------------------- 283 G4double G4GDMLEvaluator::GetConstant(const G4String& name) 284 { 285 if(IsVariable(name)) 286 { 287 G4String error_msg = 288 "Constant '" + name + "' is not defined! It is a variable!"; 289 G4Exception("G4GDMLEvaluator::GetConstant()", "InvalidSetup", 290 FatalException, error_msg); 291 } 292 if(!eval.findVariable(name)) 293 { 294 G4String error_msg = "Constant '" + name + "' is not defined!"; 295 G4Exception("G4GDMLEvaluator::GetConstant()", "InvalidSetup", 296 FatalException, error_msg); 297 } 298 return Evaluate(name); 299 } 300 301 // -------------------------------------------------------------------- 302 G4double G4GDMLEvaluator::GetVariable(const G4String& name) 303 { 304 if(!IsVariable(name)) 305 { 306 G4String error_msg = "Variable '" + name + "' is not a defined!"; 307 G4Exception("G4GDMLEvaluator::GetVariable()", "InvalidSetup", 308 FatalException, error_msg); 309 } 310 return Evaluate(name); 311 } 312 313 // -------------------------------------------------------------------- 314 G4String G4GDMLEvaluator::ConvertToString(G4int ival) 315 { 316 std::ostringstream os; 317 os << ival; 318 G4String vl = os.str(); 319 return vl; 320 } 321 322 // -------------------------------------------------------------------- 323 G4String G4GDMLEvaluator::ConvertToString(G4double dval) 324 { 325 std::ostringstream os; 326 os << dval; 327 G4String vl = os.str(); 328 return vl; 329 } 330