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