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