1 |
# $Id$ |
# $Id$ |
2 |
""" A simple tool to handel parameters for a simulation in easy way |
""" |
3 |
The idea is that all parameters are stored in a single object in a hierachical form |
A simple tool to handle parameters for a simulation in easy way. |
4 |
and can accessed using python's attribute notation. For instance: |
|
5 |
|
The idea is that all parameters are stored in a single object in a |
6 |
|
hierachical form and can accessed using python's attribute notation. |
7 |
|
For instance:: |
8 |
|
|
9 |
parm.parm2.alpha=814. |
parm.parm2.alpha=814. |
10 |
parm.parm1.gamma=0. |
parm.parm1.gamma=0. |
20 |
parm.parm1.parm11.gamma2=2. |
parm.parm1.parm11.gamma2=2. |
21 |
parm.parm1.parm11.gamma3=3. |
parm.parm1.parm11.gamma3=3. |
22 |
|
|
23 |
This structure can be stored/defined through an XML file parm.xml: |
This structure can be stored/defined through an XML file parm.xml:: |
|
|
|
|
<?xml version="1.0"?> |
|
|
<ESyS> |
|
|
<Component type="Geodynamics"> |
|
|
<Name>parm1</Name> |
|
|
<Description> |
|
|
a few examples of parameters |
|
|
</Description> |
|
|
<Parameter><Item>gamma</Item><Value>0.</Value></Parameter> |
|
|
<Parameter type="int"><Item>dim</Item><Value>2</Value></Parameter> |
|
|
<Parameter type="real"><Item>tol_v</Item><Value>0.001</Value></Parameter> |
|
|
<Parameter type="string"><Item>output_file</Item><Value>/tmp/u.%3.3d.dx</Value></Parameter> |
|
|
<Parameter type="bool"><Item>runFlag</Item><Value>true</Value></Parameter> |
|
|
<Parameter type="real" sequence="single"><Item>T</Item><Value>1.</Value><Value>2</Value></Parameter> |
|
|
<Parameter type="real" sequence="list"><Item>x1</Item><Value>-1.</Value><Value>2</Value></Parameter> |
|
|
<Parameter type="real" sequence="tuple"><Item>x2</Item><Value>10</Value><Value>11</Value></Parameter> |
|
|
<Parameter sequence="tuple"><Item>x3</Item><Value>-10.</Value></Parameter> |
|
|
<Component> |
|
|
<Name>parm11</Name> |
|
|
<Description> |
|
|
a sub compoment |
|
|
</Description> |
|
|
<Parameter><Item>gamma1</Item><Value>1.</Value></Parameter> |
|
|
<Parameter><Item>gamma2</Item><Value>2.</Value></Parameter> |
|
|
<Parameter><Item>gamma3</Item><Value>3.</Value></Parameter> |
|
|
</Component> |
|
|
</Component> |
|
|
<Component type="Geodynamics"> |
|
|
<Name>parm2</Name> |
|
|
<Description> |
|
|
another component |
|
|
</Description> |
|
|
<Parameter><Item>alpha</Item><Value>0814</Value></Parameter> |
|
|
</Component> |
|
|
</ESyS> |
|
24 |
|
|
25 |
|
<?xml version="1.0"?> |
26 |
|
<ESyS> |
27 |
|
<Component type="Geodynamics"> |
28 |
|
<Name>parm1</Name> |
29 |
|
<Description> |
30 |
|
a few examples of parameters |
31 |
|
</Description> |
32 |
|
<Parameter><Item>gamma</Item><Value>0.</Value></Parameter> |
33 |
|
<Parameter type="int"><Item>dim</Item><Value>2</Value></Parameter> |
34 |
|
<Parameter type="real"><Item>tol_v</Item><Value>0.001</Value></Parameter> |
35 |
|
<Parameter type="string"><Item>output_file</Item><Value>/tmp/u.%3.3d.dx</Value></Parameter> |
36 |
|
<Parameter type="bool"><Item>runFlag</Item><Value>true</Value></Parameter> |
37 |
|
<Parameter type="real" sequence="single"><Item>T</Item><Value>1.</Value><Value>2</Value></Parameter> |
38 |
|
<Parameter type="real" sequence="list"><Item>x1</Item><Value>-1.</Value><Value>2</Value></Parameter> |
39 |
|
<Parameter type="real" sequence="tuple"><Item>x2</Item><Value>10</Value><Value>11</Value></Parameter> |
40 |
|
<Parameter sequence="tuple"><Item>x3</Item><Value>-10.</Value></Parameter> |
41 |
|
<Component> |
42 |
|
<Name>parm11</Name> |
43 |
|
<Description> |
44 |
|
a sub compoment |
45 |
|
</Description> |
46 |
|
<Parameter><Item>gamma1</Item><Value>1.</Value></Parameter> |
47 |
|
<Parameter><Item>gamma2</Item><Value>2.</Value></Parameter> |
48 |
|
<Parameter><Item>gamma3</Item><Value>3.</Value></Parameter> |
49 |
|
</Component> |
50 |
|
<Component type="Geodynamics"> |
51 |
|
<Name>parm2</Name> |
52 |
|
<Description> |
53 |
|
another component |
54 |
|
</Description> |
55 |
|
<Parameter><Item>alpha</Item><Value>0814</Value></Parameter> |
56 |
|
</Component> |
57 |
|
</ESyS> |
58 |
""" |
""" |
59 |
|
|
60 |
|
__copyright__=""" Copyright (c) 2006 by ACcESS MNRF |
61 |
|
http://www.access.edu.au |
62 |
|
Primary Business: Queensland, Australia""" |
63 |
|
__licence__="""Licensed under the Open Software License version 3.0 |
64 |
|
http://www.opensource.org/licences/osl-3.0.php""" |
65 |
|
|
66 |
import types |
import types |
67 |
from xml.dom import minidom |
from xml.dom import minidom |
68 |
from string import atoi,atof |
from string import atoi,atof |
69 |
|
|
70 |
class ESySParameters: |
class ESySParameters: |
71 |
"""is an object to store simulation parameters in the form of a tree and |
""" |
72 |
access their values in an easy form |
Is an object to store simulation parameters in the form of a tree and |
73 |
|
access their values in an easy form |
74 |
|
|
75 |
Leaves of an ESySParameters objects can be |
Leaves of an ESySParameters object can be: |
76 |
|
|
77 |
|
- a single real number or a list or tuple of real numbers |
78 |
|
- a single integer number or a list or tuple of integer numbers |
79 |
|
- a single strings or a list or tuple of strings |
80 |
|
- a single boolean value or a list or tuple of boolean values |
81 |
|
- a ESySParameters object |
82 |
|
- any other object (not considered by writeESySXML and writeXML) |
83 |
|
|
84 |
|
Example how to create an ESySParameters object:: |
85 |
|
|
86 |
|
parm=ESySParameters() |
87 |
|
parm.parm1=ESySParameters() |
88 |
|
parm.parm1.gamma=0. |
89 |
|
parm.parm1.dim=2 |
90 |
|
parm.parm1.tol_v=0.001 |
91 |
|
parm.parm1.output_file="/tmp/u.%3.3d.dx" |
92 |
|
parm.parm1.runFlag=True |
93 |
|
parm.parm1.T=1. |
94 |
|
parm.parm1.x1=[-1.,2] |
95 |
|
parm.parm1.x2=(10.,11) |
96 |
|
parm.parm1.x3=(-10.,) |
97 |
|
parm.parm1.parm11=ESySParameters() |
98 |
|
parm.parm1.parm11.gamma1=1. |
99 |
|
parm.parm1.parm11.gamma2=2. |
100 |
|
parm.parm1.parm11.gamma3=3. |
101 |
|
parm.parm2=ESySParameters() |
102 |
|
parm.parm2.alpha=814. |
103 |
|
|
104 |
a single real number or a list or tuple of real numbers |
print parm |
|
a single integer number or a list or tuple of integer numbers |
|
|
a single strings or a list or tuple of strings |
|
|
a single boolean value or a list or tuple of boolean values |
|
|
a ESySParameters object |
|
|
any other object (not considered by writeESySXML and writeXML) |
|
|
|
|
|
Example how to create an ESySParameters object: |
|
|
|
|
|
parm=ESySParameters() |
|
|
parm.parm1=ESySParameters() |
|
|
parm.parm1.gamma=0. |
|
|
parm.parm1.dim=2 |
|
|
parm.parm1.tol_v=0.001 |
|
|
parm.parm1.output_file="/tmp/u.%3.3d.dx" |
|
|
parm.parm1.runFlag=True |
|
|
parm.parm1.T=1. |
|
|
parm.parm1.x1=[-1.,2] |
|
|
parm.parm1.x2=(10.,11) |
|
|
parm.parm1.x3=(-10.,) |
|
|
parm.parm1.parm11=ESySParameters() |
|
|
parm.parm1.parm11.gamma1=1. |
|
|
parm.parm1.parm11.gamma2=2. |
|
|
parm.parm1.parm11.gamma3=3. |
|
|
parm.parm2=ESySParameters() |
|
|
parm.parm2.alpha=814. |
|
|
|
|
|
print parm |
|
105 |
|
|
106 |
Output is |
Output is:: |
107 |
|
|
108 |
(parm1=(dim=2,output_file=/tmp/u.%3.3d.dx,parm11=(gamma3=3.0,gamma2=2.0,gamma1=1.0), |
(parm1=(dim=2,output_file=/tmp/u.%3.3d.dx,parm11=(gamma3=3.0,gamma2=2.0,gamma1=1.0), |
109 |
tol_v=0.001,T=1.0,x2=(10,),x3=(-10,),runFlag=True,x1=[-1.0, 2.0],gamma=0.0),parm2=(alpha=814.0)) |
tol_v=0.001,T=1.0,x2=(10,),x3=(-10,),runFlag=True,x1=[-1.0, 2.0],gamma=0.0),parm2=(alpha=814.0)) |
110 |
|
|
111 |
Notice that parm.parm1.x1 is now a list of two floats although it is defined by a list of a float and an integer. |
Notice that C{parm.parm1.x1} is now a list of two floats although it is |
112 |
ESySParameter is trying to use the same type for all items in a list or a tuple. |
defined by a list of a float and an integer. ESySParameter is trying to |
113 |
|
use the same type for all items in a list or a tuple. |
114 |
""" |
""" |
115 |
|
|
116 |
def __init__(self,description="none",type=None): |
def __init__(self,description="none",type=None): |
117 |
self.setDescription(description) |
self.setDescription(description) |
118 |
self.setType(type) |
self.setType(type) |
119 |
|
|
120 |
def getTypeName(self): |
def getTypeName(self): |
121 |
if self.__type==None: |
if self.__type==None: |
122 |
return None |
return None |
123 |
else: |
else: |
124 |
return self.__type.__str__() |
return self.__type.__str__() |
125 |
|
|
126 |
def getDescription(self): |
def getDescription(self): |
127 |
return self.__description |
return self.__description |
128 |
|
|
129 |
def setType(self,type=None): |
def setType(self,type=None): |
130 |
self.__type=type |
self.__type=type |
131 |
|
|
132 |
def setDescription(self,description="none"): |
def setDescription(self,description="none"): |
133 |
self.__description=description |
self.__description=description |
134 |
|
|
135 |
def __str__(self): |
def __str__(self): |
136 |
"""returns a string representation""" |
""" |
137 |
|
Returns a string representation. |
138 |
|
""" |
139 |
out="" |
out="" |
140 |
for name,value in self.__dict__.iteritems(): |
for name,value in self.__dict__.iteritems(): |
141 |
if name[0]!="_": |
if name[0]!="_": |
145 |
out=out+","+name+"="+str(value) |
out=out+","+name+"="+str(value) |
146 |
return "("+out+")" |
return "("+out+")" |
147 |
|
|
148 |
def __setattr__(self,name,value): |
def __setattr__(self,name,value): |
149 |
"""defines attribute name and assigns value. if name does not start |
""" |
150 |
with an underscore value has to be a valid Parameter.""" |
Defines attribute C{name} and assigns C{value}. If name does not start |
151 |
name=name.replace(" ","_") |
with an underscore value has to be a valid Parameter. |
152 |
if name[0]!="_": |
""" |
153 |
if value==None: |
name=name.replace(" ","_") |
154 |
self.__dict__[name]=value |
if name[0]!="_": |
155 |
elif isinstance(value,ESySParameters): |
if value==None: |
156 |
self.__dict__[name]=value |
self.__dict__[name]=value |
157 |
elif isinstance(value,types.BooleanType): |
elif isinstance(value,ESySParameters): |
158 |
self.__dict__[name]=value |
self.__dict__[name]=value |
159 |
elif isinstance(value,types.ListType): |
elif isinstance(value,types.BooleanType): |
160 |
self.__dict__[name]=_mkSameType(value) |
self.__dict__[name]=value |
161 |
elif isinstance(value,types.TupleType): |
elif isinstance(value,types.ListType): |
162 |
self.__dict__[name]=tuple(_mkSameType(value)) |
self.__dict__[name]=_mkSameType(value) |
163 |
elif isinstance(value,types.BooleanType): |
elif isinstance(value,types.TupleType): |
164 |
self.__dict__[name]=value |
self.__dict__[name]=tuple(_mkSameType(value)) |
165 |
elif isinstance(value,types.IntType): |
elif isinstance(value,types.BooleanType): |
166 |
self.__dict__[name]=value |
self.__dict__[name]=value |
167 |
elif isinstance(value,types.FloatType): |
elif isinstance(value,types.IntType): |
168 |
self.__dict__[name]=value |
self.__dict__[name]=value |
169 |
elif isinstance(value,types.StringType) or isinstance(value,types.UnicodeType): |
elif isinstance(value,types.FloatType): |
170 |
self.__dict__[name]=str(value) |
self.__dict__[name]=value |
171 |
else: |
elif isinstance(value,types.StringType) or isinstance(value,types.UnicodeType): |
172 |
|
self.__dict__[name]=str(value) |
173 |
|
else: |
174 |
|
self.__dict__[name]=value |
175 |
|
else: |
176 |
self.__dict__[name]=value |
self.__dict__[name]=value |
|
else: |
|
|
self.__dict__[name]=value |
|
177 |
|
|
178 |
def writeXML(self,iostream): |
def writeXML(self,iostream): |
179 |
"""writes the object as an XML object into an IO stream""" |
""" |
180 |
|
Writes the object as an XML object into an IO stream. |
181 |
|
""" |
182 |
for name,value in self.__dict__.iteritems(): |
for name,value in self.__dict__.iteritems(): |
183 |
if name[0]!="_": |
if name[0]!="_": |
184 |
if isinstance(value,ESySParameters): |
if isinstance(value,ESySParameters): |
212 |
iostream.write("</%s>\n"%_PARAMETER) |
iostream.write("</%s>\n"%_PARAMETER) |
213 |
|
|
214 |
|
|
215 |
def writeProperties(self, iostream, nameSpace = None): |
def writeProperties(self, iostream, nameSpace = None): |
216 |
"""writes the object as a property list to an IO stream""" |
""" |
217 |
|
Writes the object as a property list to an IO stream. |
218 |
|
""" |
219 |
if nameSpace != None and nameSpace != "": |
if nameSpace != None and nameSpace != "": |
220 |
nameSpace += "."; |
nameSpace += "."; |
221 |
for name,value in self.__dict__.iteritems(): |
for name,value in self.__dict__.iteritems(): |
234 |
type=_getTypeName(value) |
type=_getTypeName(value) |
235 |
iostream.write("%s = %s\n" % (nameSpace + name, value.__str__())) |
iostream.write("%s = %s\n" % (nameSpace + name, value.__str__())) |
236 |
|
|
237 |
def writeESySXML(self,iostream): |
def writeESySXML(self,iostream): |
238 |
"""writes an ESyS XML file""" |
""" |
239 |
|
Writes an ESyS XML file. |
240 |
|
""" |
241 |
iostream.write("<?xml version=\"1.0\"?><ESyS>") |
iostream.write("<?xml version=\"1.0\"?><ESyS>") |
242 |
self.writeXML(iostream) |
self.writeXML(iostream) |
243 |
iostream.write("</ESyS>") |
iostream.write("</ESyS>") |
244 |
|
|
245 |
def readESySXMLFile(filename): |
def readESySXMLFile(filename): |
246 |
"""reads an ESyS XML file and returns it as a ESySParameter object""" |
""" |
247 |
|
Reads an ESyS XML file and returns it as a ESySParameter object. |
248 |
|
""" |
249 |
return _readParametersFromDOM(minidom.parse(filename).getElementsByTagName(_ESYS)[0]) |
return _readParametersFromDOM(minidom.parse(filename).getElementsByTagName(_ESYS)[0]) |
250 |
|
|
251 |
|
|
271 |
|
|
272 |
|
|
273 |
def _mkSameType(list): |
def _mkSameType(list): |
274 |
"""returns list where all items in the list have the same type""" |
""" |
275 |
|
Returns list where all items in the list have the same type. |
276 |
|
""" |
277 |
out=[] |
out=[] |
278 |
if len(list)>0: |
if len(list)>0: |
279 |
type=0 |
type=0 |
316 |
return out |
return out |
317 |
|
|
318 |
def _getTypeNameOfList(values): |
def _getTypeNameOfList(values): |
319 |
"""returns the type of the parameters in list values""" |
""" |
320 |
|
Returns the type of the parameters in list values. |
321 |
|
""" |
322 |
if len(values)==0: |
if len(values)==0: |
323 |
type=_PARAMETER_TYPE_UNKNOWN |
type=_PARAMETER_TYPE_UNKNOWN |
324 |
else: |
else: |
326 |
return type |
return type |
327 |
|
|
328 |
def _getTypeName(value): |
def _getTypeName(value): |
329 |
"""returns the type of the parameter value""" |
""" |
330 |
|
Returns the type of the parameter value. |
331 |
|
""" |
332 |
if isinstance(value,types.FloatType): |
if isinstance(value,types.FloatType): |
333 |
type=_PARAMETER_TYPE_REAL |
type=_PARAMETER_TYPE_REAL |
334 |
elif isinstance(value,types.BooleanType): |
elif isinstance(value,types.BooleanType): |
343 |
|
|
344 |
|
|
345 |
def _extractStrippedValue(dom): |
def _extractStrippedValue(dom): |
346 |
"""exracts a string from a DOM node""" |
""" |
347 |
|
Exracts a string from a DOM node. |
348 |
|
""" |
349 |
out="" |
out="" |
350 |
for i in dom.childNodes: |
for i in dom.childNodes: |
351 |
s=i.nodeValue.strip() |
s=i.nodeValue.strip() |
427 |
# test section: |
# test section: |
428 |
if (__name__=="__main__"): |
if (__name__=="__main__"): |
429 |
def test(parm): |
def test(parm): |
430 |
if parm.parm1.gamma!=0. : raise IOError,"unexpected value for parm.parm1.gamma" |
if parm.parm1.gamma!=0. : |
431 |
if parm.parm1.dim!=2: raise IOError,"unexpected value for parm.parm1.dim" |
raise IOError,"unexpected value for parm.parm1.gamma" |
432 |
if parm.parm1.tol_v!=0.001: raise IOError,"unexpected value for parm.parm1.tol_v" |
if parm.parm1.dim!=2: |
433 |
if parm.parm1.output_file!="/tmp/u.%3.3d.dx": raise IOError,"unexpected value for parm.parm1.output_file" |
raise IOError,"unexpected value for parm.parm1.dim" |
434 |
if parm.parm1.runFlag!=True: raise IOError,"unexpected value for parm.parm1.runFlag" |
if parm.parm1.tol_v!=0.001: |
435 |
if parm.parm1.T!=1.: raise IOError,"unexpected value for parm.parm1.T" |
raise IOError,"unexpected value for parm.parm1.tol_v" |
436 |
if parm.parm1.x1[0]!=-1.: raise IOError,"unexpected value for parm.parm1.x1[0]" |
if parm.parm1.output_file!="/tmp/u.%3.3d.dx": |
437 |
if parm.parm1.x1[1]!=2.: raise IOError,"unexpected value for parm.parm1.x1[1]" |
raise IOError,"unexpected value for parm.parm1.output_file" |
438 |
if parm.parm1.x2[0]!=10.: raise IOError,"unexpected value for parm.parm1.x2[0]" |
if parm.parm1.runFlag!=True: |
439 |
if parm.parm1.x2[1]!=11.: raise IOError,"unexpected value for parm.parm1.x2[1]" |
raise IOError,"unexpected value for parm.parm1.runFlag" |
440 |
if parm.parm1.x3[0]!=-10: raise IOError,"unexpected value for parm.parm1.x3[0]" |
if parm.parm1.T!=1.: |
441 |
if parm.parm1.parm11.gamma1!=1.: raise IOError,"unexpected value for parm.parm1.parm11.gamma1" |
raise IOError,"unexpected value for parm.parm1.T" |
442 |
if parm.parm1.parm11.gamma2!=2.: raise IOError,"unexpected value for parm.parm1.parm11.gamma2" |
if parm.parm1.x1[0]!=-1.: |
443 |
if parm.parm1.parm11.gamma3!=3.: raise IOError,"unexpected value for parm.parm1.parm11.gamma3" |
raise IOError,"unexpected value for parm.parm1.x1[0]" |
444 |
if parm.parm2.alpha!=814.: raise IOError,"unexpected value for parm.parm2.alpha" |
if parm.parm1.x1[1]!=2.: |
445 |
|
raise IOError,"unexpected value for parm.parm1.x1[1]" |
446 |
|
if parm.parm1.x2[0]!=10.: |
447 |
|
raise IOError,"unexpected value for parm.parm1.x2[0]" |
448 |
|
if parm.parm1.x2[1]!=11.: |
449 |
|
raise IOError,"unexpected value for parm.parm1.x2[1]" |
450 |
|
if parm.parm1.x3[0]!=-10: |
451 |
|
raise IOError,"unexpected value for parm.parm1.x3[0]" |
452 |
|
if parm.parm1.parm11.gamma1!=1.: |
453 |
|
raise IOError,"unexpected value for parm.parm1.parm11.gamma1" |
454 |
|
if parm.parm1.parm11.gamma2!=2.: |
455 |
|
raise IOError,"unexpected value for parm.parm1.parm11.gamma2" |
456 |
|
if parm.parm1.parm11.gamma3!=3.: |
457 |
|
raise IOError,"unexpected value for parm.parm1.parm11.gamma3" |
458 |
|
if parm.parm2.alpha!=814.: |
459 |
|
raise IOError,"unexpected value for parm.parm2.alpha" |
460 |
|
|
461 |
print "@@@ explicit construction" |
print "@@@ explicit construction" |
462 |
parm=ESySParameters() |
parm=ESySParameters() |
523 |
parm3=readESySXMLFile("/tmp/test2.xml") |
parm3=readESySXMLFile("/tmp/test2.xml") |
524 |
print parm3 |
print parm3 |
525 |
test(parm3) |
test(parm3) |
526 |
|
|
527 |
|
# vim: expandtab shiftwidth=4: |