Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/persistency/gdml/src/G4GDMLEvaluator.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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