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