/[escript]/trunk/escript/py_src/modelframe.py
ViewVC logotype

Annotation of /trunk/escript/py_src/modelframe.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1387 - (hide annotations)
Fri Jan 11 07:45:26 2008 UTC (11 years, 10 months ago) by trankine
Original Path: temp/escript/py_src/modelframe.py
File MIME type: text/x-python
File size: 46660 byte(s)
Restore the trunk that existed before the windows changes were committed to the (now moved to branches) old trunk.
1 ksteube 1312 #
2 jgs 121 # $Id$
3 ksteube 1312 #
4     #######################################################
5     #
6     # Copyright 2003-2007 by ACceSS MNRF
7     # Copyright 2007 by University of Queensland
8     #
9     # http://esscc.uq.edu.au
10     # Primary Business: Queensland, Australia
11     # Licensed under the Open Software License version 3.0
12     # http://www.opensource.org/licenses/osl-3.0.php
13     #
14     #######################################################
15     #
16 jgs 121
17 gross 637 """
18     Environment for implementing models in escript
19    
20     @var __author__: name of author
21     @var __copyright__: copyrights
22     @var __license__: licence agreement
23     @var __url__: url entry point on documentation
24     @var __version__: version
25     @var __date__: date of the version
26     """
27    
28     __author__="Lutz Gross, l.gross@uq.edu.au"
29 elspeth 609 __copyright__=""" Copyright (c) 2006 by ACcESS MNRF
30     http://www.access.edu.au
31     Primary Business: Queensland, Australia"""
32 elspeth 614 __license__="""Licensed under the Open Software License version 3.0
33     http://www.opensource.org/licenses/osl-3.0.php"""
34 gross 637 __url__="http://www.iservo.edu.au/esys"
35     __version__="$Revision$"
36     __date__="$Date$"
37 elspeth 609
38 gross 637
39 jgs 122 from types import StringType,IntType,FloatType,BooleanType,ListType,DictType
40     from sys import stdout
41 elspeth 871 import numarray
42     import operator
43 jgs 123 import itertools
44 gross 975 import time
45     import os
46 jgs 121
47 jgs 123 # import the 'set' module if it's not defined (python2.3/2.4 difference)
48     try:
49     set
50     except NameError:
51     from sets import Set as set
52    
53 jgs 122 from xml.dom import minidom
54 jgs 121
55    
56 jgs 123 def all(seq):
57     for x in seq:
58     if not x:
59     return False
60     return True
61    
62 jgs 147 def any(seq):
63     for x in seq:
64     if x:
65     return True
66     return False
67    
68 jgs 150 def importName(modulename, name):
69     """ Import a named object from a module in the context of this function,
70     which means you should use fully qualified module paths.
71     Return None on failure.
72    
73     This function from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52241
74     """
75     module = __import__(modulename, globals(), locals(), [name])
76    
77     try:
78     return vars(module)[name]
79     except KeyError:
80     raise ImportError("Could not import %s from %s" % (name, modulename))
81    
82 gross 918 class ESySXMLParser(object):
83 jgs 147 """
84 gross 918 parser for ESysXML file
85     """
86     def __init__(self,xml, debug=False):
87     self.__dom = minidom.parseString(xml)
88     self.__linkable_object_registry= {}
89     self.__link_registry= []
90 gross 944 self.__esys=self.__dom.getElementsByTagName('ESys')[0]
91 gross 918 self.debug=debug
92    
93     def getClassPath(self, node):
94     type = node.getAttribute("type")
95     if (node.getAttribute("module")):
96     module = node.getAttribute("module")
97     return importName(module, type)
98     else:
99     return importName("__main__", type)
100 jgs 123
101 gross 918 def setLinks(self):
102     for obj_id, link in self.__link_registry:
103     link.target = self.__linkable_object_registry[obj_id]
104 jgs 123
105 gross 918 def parse(self):
106     """
107     parser method for EsysXML and returns the list of generating ParameterSets
108     """
109     found=[]
110     for node in self.__esys.childNodes:
111     if isinstance(node, minidom.Element):
112     if node.tagName == 'Simulation':
113     found.append(Simulation.fromDom(self, node))
114     elif node.tagName == 'Model':
115     found.append(self.getClassPath(node).fromDom(self, node))
116     elif node.tagName == 'ParameterSet':
117     found.append(self.getClassPath(node).fromDom(self, node))
118     else:
119     raise "Invalid type, %r" % node.getAttribute("type")
120     self.setLinks()
121     return found
122    
123     def registerLink(self,obj_id, link):
124     self.__link_registry.append((int(obj_id),link))
125    
126     def registerLinkableObject(self,obj, node):
127     id_str=node.getAttribute('id').strip()
128     if len(id_str)>0:
129     id=int(id_str)
130     if self.__linkable_object_registry.has_key(id):
131     raise ValueError("Object id %s already exists."%id)
132     else:
133     self.__linkable_object_registry[id]=obj
134    
135     def getComponent(self, node):
136     """
137     returns a single component + rank from a simulation
138     parser method for EsysXML and returns the list of generating ParameterSets
139     """
140     rank = int(node.getAttribute("rank"))
141     for n in node.childNodes:
142     if isinstance(n, minidom.Element):
143     if n.tagName == 'Simulation':
144     return (rank, Simulation.fromDom(self, n))
145     elif n.tagName == 'Model':
146     return (rank, self.getClassPath(n).fromDom(self, n))
147     elif n.tagName == 'ParameterSet':
148     return (rank, self.getClassPath(n).fromDom(self, n))
149     else:
150     raise ValueError("illegal component type %s"%n.tagName)
151     raise ValueError("cannot resolve Component")
152    
153     class ESySXMLCreator(object):
154     """
155     creates an XML Dom representation
156     """
157     def __init__(self):
158     self.__dom=minidom.Document()
159     self.__esys =self.__dom.createElement('ESys')
160     self.__dom.appendChild(self.__esys)
161     self.__linkable_object_registry={}
162     self.__number_sequence = itertools.count(100)
163     def getRoot(self):
164     return self.__esys
165     def createElement(self,name):
166     return self.__dom.createElement(name)
167     def createTextNode(self,name):
168     return self.__dom.createTextNode(name)
169     def getElementById(self,name):
170     return self.__dom.getElementById(name)
171     def createDataNode(self, tagName, data):
172     """
173     C{createDataNode}s are the building blocks of the xml documents constructed in
174     this module.
175    
176     @param tagName: the associated xml tag
177     @param data: the values in the tag
178     """
179     n = self.createElement(tagName)
180     n.appendChild(self.createTextNode(str(data)))
181     return n
182     def getLinkableObjectId(self, obj):
183     for id, o in self.__linkable_object_registry.items():
184     if o == obj: return id
185     id =self.__number_sequence.next()
186     self.__linkable_object_registry[id]=obj
187     return id
188    
189     def registerLinkableObject(self, obj, node):
190     """
191     returns a unique object id for object obj
192     """
193     id=self.getLinkableObjectId(obj)
194     node.setAttribute('id',str(id))
195     node.setIdAttribute("id")
196    
197     def includeTargets(self):
198     target_written=True
199     while target_written:
200     targetsList =self.__dom.getElementsByTagName('Target')
201     target_written=False
202     for element in targetsList:
203     targetId = int(element.firstChild.nodeValue.strip())
204     if self.getElementById(str(targetId)): continue
205     targetObj = self.__linkable_object_registry[targetId]
206     targetObj.toDom(self, self.__esys)
207     target_written=True
208    
209     def toprettyxml(self):
210     self.includeTargets()
211     return self.__dom.toprettyxml()
212    
213 jgs 122 class Link:
214 jgs 123 """
215 jgs 149 A Link makes an attribute of an object callable::
216    
217 jgs 123 o.object()
218     o.a=8
219     l=Link(o,"a")
220     assert l()==8
221     """
222    
223     def __init__(self,target,attribute=None):
224 jgs 126 """
225 jgs 149 Creates a link to the object target. If attribute is given, the link is
226 jgs 123 establised to this attribute of the target. Otherwise the attribute is
227 jgs 126 undefined.
228     """
229 jgs 123 self.target = target
230     self.attribute = None
231     self.setAttributeName(attribute)
232 gross 912
233 gross 938 def getTarget(self):
234     """
235     returns the target
236     """
237     return self.target
238 gross 912 def getAttributeName(self):
239     """
240     returns the name of the attribute the link is pointing to
241     """
242     return self.attribute
243 jgs 123
244     def setAttributeName(self,attribute):
245 jgs 126 """
246 jgs 149 Set a new attribute name to be collected from the target object. The
247 jgs 126 target object must have the attribute with name attribute.
248     """
249 jgs 147 if attribute and self.target:
250     if isinstance(self.target,LinkableObject):
251     if not self.target.hasAttribute(attribute):
252     raise AttributeError("%s: target %s has no attribute %s."%(self, self.target, attribute))
253     else:
254     if not hasattr(self.target,attribute):
255     raise AttributeError("%s: target %s has no attribute %s."%(self, self.target, attribute))
256 jgs 123 self.attribute = attribute
257    
258     def hasDefinedAttributeName(self):
259 jgs 126 """
260 jgs 149 Returns true if an attribute name is set.
261 jgs 126 """
262 jgs 123 return self.attribute != None
263    
264     def __repr__(self):
265 jgs 126 """
266 jgs 149 Returns a string representation of the link.
267 jgs 126 """
268 jgs 123 if self.hasDefinedAttributeName():
269     return "<Link to attribute %s of %s>" % (self.attribute, self.target)
270     else:
271     return "<Link to target %s>" % self.target
272    
273     def __call__(self,name=None):
274 jgs 126 """
275 jgs 149 Returns the value of the attribute of the target object. If the
276 jgs 126 atrribute is callable then the return value of the call is returned.
277     """
278 jgs 123 if name:
279     out=getattr(self.target, name)
280     else:
281     out=getattr(self.target, self.attribute)
282 jgs 121
283 jgs 123 if callable(out):
284     return out()
285     else:
286     return out
287 jgs 121
288 gross 918 def toDom(self, esysxml, node):
289 jgs 126 """
290 jgs 149 C{toDom} method of Link. Creates a Link node and appends it to the
291 gross 918 current XML esysxml.
292 jgs 126 """
293 gross 918 link = esysxml.createElement('Link')
294 jgs 147 assert (self.target != None), ("Target was none, name was %r" % self.attribute)
295 gross 918 link.appendChild(esysxml.createDataNode('Target', esysxml.getLinkableObjectId(self.target)))
296 jgs 123 # this use of id will not work for purposes of being able to retrieve the intended
297     # target from the xml later. I need a better unique identifier.
298     assert self.attribute, "You can't xmlify a Link without a target attribute"
299 gross 918 link.appendChild(esysxml.createDataNode('Attribute', self.attribute))
300 jgs 123 node.appendChild(link)
301 jgs 121
302 gross 918 def fromDom(cls, esysxml, node):
303     targetid = int(node.getElementsByTagName("Target")[0].firstChild.nodeValue.strip())
304     attribute =str(node.getElementsByTagName("Attribute")[0].firstChild.nodeValue.strip())
305 jgs 123 l = cls(None, attribute)
306 gross 918 esysxml.registerLink(targetid, l)
307 jgs 123 return l
308 jgs 121
309 jgs 123 fromDom = classmethod(fromDom)
310    
311 jgs 122 class LinkableObject(object):
312 jgs 123 """
313     An object that allows to link its attributes to attributes of other objects
314 jgs 149 via a Link object. For instance::
315 jgs 123
316     p = LinkableObject()
317     p.x = Link(o,"name")
318     print p.x
319    
320 jgs 149 links attribute C{x} of C{p} to the attribute name of object C{o}.
321 jgs 121
322 jgs 149 C{p.x} will contain the current value of attribute C{name} of object
323     C{o}.
324 jgs 121
325 jgs 149 If the value of C{getattr(o, "name")} is callable, C{p.x} will return
326     the return value of the call.
327 jgs 123 """
328    
329    
330 gross 918 def __init__(self, id = None, debug=False):
331 jgs 149 """
332     Initializes LinkableObject so that we can operate on Links
333     """
334 jgs 123 self.debug = debug
335     self.__linked_attributes={}
336 gross 918
337 jgs 123 def trace(self, msg):
338     """
339 jgs 149 If debugging is on, print the message, otherwise do nothing
340     """
341 jgs 123 if self.debug:
342 jgs 147 print "%s: %s"%(str(self),msg)
343 jgs 123
344     def __getattr__(self,name):
345 jgs 149 """
346     Returns the value of attribute name. If the value is a Link object the
347     object is called and the return value is returned.
348     """
349 jgs 123 out = self.getAttributeObject(name)
350     if isinstance(out,Link):
351     return out()
352     else:
353     return out
354    
355     def getAttributeObject(self,name):
356 jgs 149 """
357     Return the object stored for attribute name.
358     """
359 jgs 123
360     if self.__dict__.has_key(name):
361     return self.__dict__[name]
362    
363     if self.__linked_attributes.has_key(name):
364     return self.__linked_attributes[name]
365    
366 jgs 147 if self.__class__.__dict__.has_key(name):
367     return self.__class.__dict__[name]
368    
369 jgs 123 raise AttributeError,"No attribute %s."%name
370    
371 jgs 147 def hasAttribute(self,name):
372 jgs 149 """
373     Returns True if self as attribute name.
374     """
375 jgs 147 return self.__dict__.has_key(name) or self.__linked_attributes.has_key(name) or self.__class__.__dict__.has_key(name)
376    
377 jgs 123 def __setattr__(self,name,value):
378 jgs 149 """
379     Sets the value for attribute name. If value is a Link the target
380     attribute is set to name if no attribute has been specified.
381     """
382 jgs 123
383     if self.__dict__.has_key(name):
384     del self.__dict__[name]
385    
386     if isinstance(value,Link):
387     if not value.hasDefinedAttributeName():
388     value.setAttributeName(name)
389     self.__linked_attributes[name] = value
390    
391 jgs 147 self.trace("attribute %s is now linked by %s."%(name,value))
392 jgs 123 else:
393     self.__dict__[name] = value
394    
395     def __delattr__(self,name):
396 jgs 149 """
397     Removes the attribute name.
398     """
399 jgs 123
400     if self.__linked_attributes.has_key[name]:
401     del self.__linked_attributes[name]
402     elif self.__dict__.has_key(name):
403     del self.__dict__[name]
404     else:
405     raise AttributeError,"No attribute %s."%name
406    
407 jgs 122 class _ParameterIterator:
408 jgs 123 def __init__(self,parameterset):
409 jgs 121
410 jgs 123 self.__set=parameterset
411     self.__iter=iter(parameterset.parameters)
412    
413     def next(self):
414     o=self.__iter.next()
415     return (o,self.__set.getAttributeObject(o))
416    
417     def __iter__(self):
418     return self
419    
420 jgs 122 class ParameterSet(LinkableObject):
421 jgs 149 """
422     A class which allows to emphazise attributes to be written and read to XML
423 jgs 123
424 jgs 149 Leaves of an ESySParameters object can be:
425 jgs 123
426 jgs 149 - a real number
427     - a integer number
428     - a string
429     - a boolean value
430     - a ParameterSet object
431     - a Simulation object
432     - a Model object
433 elspeth 874 - a numarray object
434     - a list of booleans
435     - any other object (not considered by writeESySXML and writeXML)
436 jgs 123
437 jgs 149 Example how to create an ESySParameters object::
438 jgs 123
439 jgs 149 p11=ParameterSet(gamma1=1.,gamma2=2.,gamma3=3.)
440     p1=ParameterSet(dim=2,tol_v=0.001,output_file="/tmp/u.%3.3d.dx",runFlag=True,parm11=p11)
441     parm=ParameterSet(parm1=p1,parm2=ParameterSet(alpha=Link(p11,"gamma1")))
442 jgs 123
443 jgs 149 This can be accessed as::
444 jgs 123
445 jgs 149 parm.parm1.gamma=0.
446     parm.parm1.dim=2
447     parm.parm1.tol_v=0.001
448     parm.parm1.output_file="/tmp/u.%3.3d.dx"
449     parm.parm1.runFlag=True
450     parm.parm1.parm11.gamma1=1.
451     parm.parm1.parm11.gamma2=2.
452     parm.parm1.parm11.gamma3=3.
453     parm.parm2.alpha=1. (value of parm.parm1.parm11.gamma1)
454 jgs 123 """
455     def __init__(self, parameters=[], **kwargs):
456 jgs 149 """
457     Creates a ParameterSet with parameters parameters.
458     """
459 jgs 123 LinkableObject.__init__(self, **kwargs)
460     self.parameters = set()
461     self.declareParameters(parameters)
462 jgs 147
463     def __repr__(self):
464 gross 908 return "<%s %d>"%(self.__class__.__name__,id(self))
465 jgs 123
466     def declareParameter(self,**parameters):
467 jgs 149 """
468     Declares a new parameter(s) and its (their) initial value.
469     """
470 jgs 123 self.declareParameters(parameters)
471    
472     def declareParameters(self,parameters):
473 jgs 149 """
474     Declares a set of parameters. parameters can be a list, a dictionary
475     or a ParameterSet.
476     """
477 jgs 123 if isinstance(parameters,ListType):
478     parameters = zip(parameters, itertools.repeat(None))
479     if isinstance(parameters,DictType):
480     parameters = parameters.iteritems()
481 jgs 121
482 jgs 123 for prm, value in parameters:
483     setattr(self,prm,value)
484     self.parameters.add(prm)
485 jgs 121
486 jgs 123 def releaseParameters(self,name):
487 jgs 149 """
488     Removes parameter name from the paramameters.
489     """
490 jgs 123 if self.isParameter(name):
491     self.parameters.remove(name)
492 jgs 147 self.trace("parameter %s has been removed."%name)
493 gross 950
494     def checkLinkTargets(self, models, hash):
495     """
496 gross 952 returns a set of tuples ("<self>(<name>)", <target model>) if the parameter <name> is linked to model <target model>
497     but <target model> is not in the list models. If the a parameter is linked to another parameter set which is not in the hash list
498     the parameter set is checked for its models. hash gives the call history.
499 gross 950 """
500 gross 952 out=set()
501 gross 950 for name, value in self:
502     if isinstance(value, Link):
503     m=value.getTarget()
504 gross 952 if isinstance(m, Model):
505     if not m in models: out.add( (str(self)+"("+name+")",m) )
506     elif isinstance(m, ParameterSet) and not m in hash:
507     out|=set( [ (str(self)+"("+name+")."+f[0],f[1]) for f in m.checkLinkTargets(models, hash+[ self ] ) ] )
508     return out
509 jgs 123
510     def __iter__(self):
511 jgs 149 """
512     Creates an iterator over the parameter and their values.
513     """
514 jgs 123 return _ParameterIterator(self)
515    
516     def showParameters(self):
517 jgs 149 """
518     Returns a descrition of the parameters.
519     """
520 jgs 123 out="{"
521     notfirst=False
522     for i,v in self:
523     if notfirst: out=out+","
524     notfirst=True
525     if isinstance(v,ParameterSet):
526     out="%s\"%s\" : %s"%(out,i,v.showParameters())
527     else:
528     out="%s\"%s\" : %s"%(out,i,v)
529     return out+"}"
530    
531     def __delattr__(self,name):
532 jgs 149 """
533     Removes the attribute name.
534     """
535 jgs 123 LinkableObject.__delattr__(self,name)
536     try:
537     self.releaseParameter(name)
538     except:
539     pass
540 jgs 121
541 gross 918 def toDom(self, esysxml, node):
542 jgs 149 """
543 gross 918 C{toDom} method of Model class
544 jgs 149 """
545 gross 918 pset = esysxml.createElement('ParameterSet')
546     pset.setAttribute('type', self.__class__.__name__)
547     pset.setAttribute('module', self.__class__.__module__)
548     esysxml.registerLinkableObject(self, pset)
549     self._parametersToDom(esysxml, pset)
550 jgs 123 node.appendChild(pset)
551 jgs 121
552 gross 918 def _parametersToDom(self, esysxml, node):
553 jgs 123 for name,value in self:
554 gross 918 # convert list to numarray when possible:
555     if isinstance (value, list):
556     elem_type=-1
557     for i in value:
558     if isinstance(i, bool):
559     elem_type = max(elem_type,0)
560 gross 964 elif isinstance(i, int):
561 gross 918 elem_type = max(elem_type,1)
562 gross 964 elif isinstance(i, float):
563 gross 918 elem_type = max(elem_type,2)
564     if elem_type == 0: value = numarray.array(value,numarray.Bool)
565     if elem_type == 1: value = numarray.array(value,numarray.Int)
566     if elem_type == 2: value = numarray.array(value,numarray.Float)
567    
568     param = esysxml.createElement('Parameter')
569 jgs 123 param.setAttribute('type', value.__class__.__name__)
570 jgs 121
571 gross 918 param.appendChild(esysxml.createDataNode('Name', name))
572 jgs 121
573 gross 918 val = esysxml.createElement('Value')
574 elspeth 875 if isinstance(value,(ParameterSet,Link,DataSource)):
575 gross 918 value.toDom(esysxml, val)
576 jgs 123 param.appendChild(val)
577 elspeth 871 elif isinstance(value, numarray.NumArray):
578     shape = value.getshape()
579     if isinstance(shape, tuple):
580     size = reduce(operator.mul, shape)
581     shape = ' '.join(map(str, shape))
582     else:
583     size = shape
584     shape = str(shape)
585    
586     arraytype = value.type()
587 gross 918 if isinstance(arraytype, numarray.BooleanType):
588     arraytype_str="Bool"
589     elif isinstance(arraytype, numarray.IntegralType):
590     arraytype_str="Int"
591     elif isinstance(arraytype, numarray.FloatingType):
592     arraytype_str="Float"
593     elif isinstance(arraytype, numarray.ComplexType):
594     arraytype_str="Complex"
595     else:
596     arraytype_str=str(arraytype)
597     numarrayElement = esysxml.createElement('NumArray')
598     numarrayElement.appendChild(esysxml.createDataNode('ArrayType', arraytype_str))
599     numarrayElement.appendChild(esysxml.createDataNode('Shape', shape))
600     numarrayElement.appendChild(esysxml.createDataNode('Data', ' '.join(
601 elspeth 871 [str(x) for x in numarray.reshape(value, size)])))
602 elspeth 874 val.appendChild(numarrayElement)
603 elspeth 871 param.appendChild(val)
604 gross 918 elif isinstance(value, list):
605     param.appendChild(esysxml.createDataNode('Value', ' '.join([str(x) for x in value]) ))
606     elif isinstance(value, (str, bool, int, float, type(None))):
607     param.appendChild(esysxml.createDataNode('Value', str(value)))
608 gross 926 elif isinstance(value, dict):
609     dic = esysxml.createElement('dictionary')
610     if len(value.keys())>0:
611     dic.setAttribute('key_type', value.keys()[0].__class__.__name__)
612     dic.setAttribute('value_type', value[value.keys()[0]].__class__.__name__)
613     for k,v in value.items():
614     i=esysxml.createElement('item')
615     i.appendChild(esysxml.createDataNode('key', k))
616     i.appendChild(esysxml.createDataNode('value', v))
617     dic.appendChild(i)
618     param.appendChild(dic)
619 jgs 123 else:
620 gross 918 raise ValueError("cannot serialize %s type to XML."%str(value.__class__))
621 jgs 123
622     node.appendChild(param)
623    
624 gross 918 def fromDom(cls, esysxml, node):
625 jgs 123 # Define a host of helper functions to assist us.
626     def _children(node):
627     """
628 jgs 149 Remove the empty nodes from the children of this node.
629 jgs 123 """
630 elspeth 871 ret = []
631     for x in node.childNodes:
632     if isinstance(x, minidom.Text):
633     if x.nodeValue.strip():
634     ret.append(x)
635     else:
636     ret.append(x)
637     return ret
638 jgs 123
639 gross 918 def _floatfromValue(esysxml, node):
640     return float(node.nodeValue.strip())
641 jgs 123
642 gross 918 def _stringfromValue(esysxml, node):
643     return str(node.nodeValue.strip())
644 jgs 126
645 gross 918 def _intfromValue(esysxml, node):
646     return int(node.nodeValue.strip())
647 jgs 126
648 gross 918 def _boolfromValue(esysxml, node):
649     return _boolfromstring(node.nodeValue.strip())
650 elspeth 266
651 gross 918 def _nonefromValue(esysxml, node):
652 elspeth 266 return None
653 elspeth 871
654 gross 918 def _numarrayfromValue(esysxml, node):
655     for node in _children(node):
656 elspeth 871 if node.tagName == 'ArrayType':
657     arraytype = node.firstChild.nodeValue.strip()
658     if node.tagName == 'Shape':
659     shape = node.firstChild.nodeValue.strip()
660     shape = [int(x) for x in shape.split()]
661     if node.tagName == 'Data':
662     data = node.firstChild.nodeValue.strip()
663     data = [float(x) for x in data.split()]
664     return numarray.reshape(numarray.array(data, type=getattr(numarray, arraytype)),
665     shape)
666 elspeth 874
667 gross 918 def _listfromValue(esysxml, node):
668     return [x for x in node.nodeValue.split()]
669 elspeth 874
670     def _boolfromstring(s):
671     if s == 'True':
672     return True
673     else:
674     return False
675 jgs 123 # Mapping from text types in the xml to methods used to process trees of that type
676     ptypemap = {"Simulation": Simulation.fromDom,
677     "Model":Model.fromDom,
678     "ParameterSet":ParameterSet.fromDom,
679     "Link":Link.fromDom,
680 elspeth 875 "DataSource":DataSource.fromDom,
681 jgs 123 "float":_floatfromValue,
682 jgs 126 "int":_intfromValue,
683 jgs 123 "str":_stringfromValue,
684 elspeth 269 "bool":_boolfromValue,
685 elspeth 874 "list":_listfromValue,
686     "NumArray":_numarrayfromValue,
687 elspeth 871 "NoneType":_nonefromValue,
688 jgs 123 }
689    
690     parameters = {}
691 gross 918 for n in _children(node):
692     ptype = n.getAttribute("type")
693     if not ptypemap.has_key(ptype):
694     raise KeyError("cannot handle parameter type %s."%ptype)
695 jgs 123
696     pname = pvalue = None
697 gross 918 for childnode in _children(n):
698 jgs 123 if childnode.tagName == "Name":
699     pname = childnode.firstChild.nodeValue.strip()
700    
701     if childnode.tagName == "Value":
702     nodes = _children(childnode)
703 gross 918 pvalue = ptypemap[ptype](esysxml, nodes[0])
704 jgs 123
705     parameters[pname] = pvalue
706    
707     # Create the instance of ParameterSet
708 gross 1042 try:
709     o = cls(debug=esysxml.debug)
710     except TypeError, inst:
711     print inst.args[0]
712     if inst.args[0]=="__init__() got an unexpected keyword argument 'debug'":
713     raise TypeError("The Model class %s __init__ needs to have argument 'debug'.")
714     else:
715     raise inst
716 jgs 123 o.declareParameters(parameters)
717 gross 918 esysxml.registerLinkableObject(o, node)
718 jgs 123 return o
719    
720     fromDom = classmethod(fromDom)
721 gross 918
722 jgs 123 def writeXML(self,ostream=stdout):
723 jgs 149 """
724     Writes the object as an XML object into an output stream.
725     """
726 gross 918 esysxml=ESySXMLCreator()
727     self.toDom(esysxml, esysxml.getRoot())
728     ostream.write(esysxml.toprettyxml())
729    
730 jgs 147 class Model(ParameterSet):
731     """
732 jgs 149 A Model object represents a processess marching over time until a
733     finalizing condition is fullfilled. At each time step an iterative
734     process can be performed and the time step size can be controlled. A
735     Model has the following work flow::
736 gross 906
737 jgs 147 doInitialization()
738 gross 906 while not terminateInitialIteration(): doInitializationiStep()
739     doInitialPostprocessing()
740 jgs 147 while not finalize():
741     dt=getSafeTimeStepSize(dt)
742     doStepPreprocessing(dt)
743     while not terminateIteration(): doStep(dt)
744     doStepPostprocessing(dt)
745     doFinalization()
746 jgs 121
747 jgs 149 where C{doInitialization}, C{finalize}, C{getSafeTimeStepSize},
748     C{doStepPreprocessing}, C{terminateIteration}, C{doStepPostprocessing},
749     C{doFinalization} are methods of the particular instance of a Model. The
750     default implementations of these methods have to be overwritten by the
751     subclass implementing a Model.
752 jgs 147 """
753 jgs 121
754 jgs 147 UNDEF_DT=1.e300
755 jgs 121
756 gross 918 def __init__(self,parameters=[],**kwargs):
757 jgs 149 """
758     Creates a model.
759 jgs 121
760 jgs 149 Just calls the parent constructor.
761 jgs 147 """
762 gross 918 ParameterSet.__init__(self, parameters=parameters,**kwargs)
763 jgs 121
764 jgs 147 def __str__(self):
765 gross 908 return "<%s %d>"%(self.__class__.__name__,id(self))
766 jgs 121
767    
768 gross 975 def setUp(self):
769     """
770     Sets up the model.
771    
772     This function may be overwritten.
773     """
774     pass
775    
776 jgs 147 def doInitialization(self):
777 jgs 149 """
778 gross 975 Initializes the time stepping scheme. This method is not called in case of a restart.
779 jgs 149
780     This function may be overwritten.
781     """
782 jgs 147 pass
783 gross 906 def doInitialStep(self):
784     """
785 gross 975 performs an iteration step in the initialization phase. This method is not called in case of a restart.
786 gross 906
787     This function may be overwritten.
788     """
789     pass
790    
791     def terminateInitialIteration(self):
792     """
793 gross 975 Returns True if iteration at the inital phase is terminated.
794 gross 906 """
795     return True
796    
797     def doInitialPostprocessing(self):
798     """
799 gross 975 finalises the initialization iteration process. This method is not called in case of a restart.
800 gross 906
801     This function may be overwritten.
802     """
803     pass
804 jgs 147
805     def getSafeTimeStepSize(self,dt):
806 jgs 149 """
807     Returns a time step size which can safely be used.
808    
809     C{dt} gives the previously used step size.
810    
811     This function may be overwritten.
812     """
813 jgs 147 return self.UNDEF_DT
814    
815     def finalize(self):
816 jgs 149 """
817     Returns False if the time stepping is finalized.
818    
819     This function may be overwritten.
820     """
821 jgs 147 return False
822 jgs 123
823 jgs 147 def doFinalization(self):
824 jgs 149 """
825     Finalizes the time stepping.
826    
827     This function may be overwritten.
828     """
829 jgs 147 pass
830    
831     def doStepPreprocessing(self,dt):
832 jgs 149 """
833     Sets up a time step of step size dt.
834    
835     This function may be overwritten.
836     """
837 jgs 147 pass
838    
839     def doStep(self,dt):
840 jgs 149 """
841     Executes an iteration step at a time step.
842    
843     C{dt} is the currently used time step size.
844    
845     This function may be overwritten.
846     """
847 jgs 147 pass
848    
849     def terminateIteration(self):
850 jgs 149 """
851     Returns True if iteration on a time step is terminated.
852     """
853 jgs 147 return True
854 gross 906
855 jgs 147
856     def doStepPostprocessing(self,dt):
857 jgs 149 """
858 gross 906 finalises the time step.
859 jgs 149
860     dt is the currently used time step size.
861    
862     This function may be overwritten.
863     """
864 jgs 147 pass
865 gross 918
866     def toDom(self, esysxml, node):
867     """
868     C{toDom} method of Model class
869     """
870     pset = esysxml.createElement('Model')
871     pset.setAttribute('type', self.__class__.__name__)
872     pset.setAttribute('module', self.__class__.__module__)
873     esysxml.registerLinkableObject(self, pset)
874     node.appendChild(pset)
875     self._parametersToDom(esysxml, pset)
876 jgs 147
877     class Simulation(Model):
878     """
879 jgs 149 A Simulation object is special Model which runs a sequence of Models.
880 jgs 121
881 jgs 149 The methods C{doInitialization}, C{finalize}, C{getSafeTimeStepSize},
882     C{doStepPreprocessing}, C{terminateIteration}, C{doStepPostprocessing},
883     C{doFinalization} are executing the corresponding methods of the models in
884     the simulation.
885 jgs 147 """
886    
887     FAILED_TIME_STEPS_MAX=20
888     MAX_ITER_STEPS=50
889 gross 836 MAX_CHANGE_OF_DT=2.
890 jgs 147
891     def __init__(self, models=[], **kwargs):
892 jgs 149 """
893     Initiates a simulation from a list of models.
894     """
895 gross 918 super(Simulation, self).__init__(**kwargs)
896 gross 975 self.declareParameter(time=0.,
897     time_step=0,
898     dt = self.UNDEF_DT)
899 gross 938 for m in models:
900     if not isinstance(m, Model):
901     raise TypeError("%s is not a subclass of Model."%m)
902 jgs 147 self.__models=[]
903     for i in range(len(models)):
904     self[i] = models[i]
905 jgs 149
906 jgs 121
907 jgs 147 def __repr__(self):
908     """
909 jgs 149 Returns a string representation of the Simulation.
910 jgs 147 """
911     return "<Simulation %r>" % self.__models
912 jgs 121
913 jgs 147 def __str__(self):
914     """
915 jgs 149 Returning Simulation as a string.
916 jgs 147 """
917     return "<Simulation %d>"%id(self)
918    
919     def iterModels(self):
920 jgs 149 """
921     Returns an iterator over the models.
922     """
923 jgs 147 return self.__models
924    
925     def __getitem__(self,i):
926 jgs 149 """
927     Returns the i-th model.
928     """
929 jgs 147 return self.__models[i]
930    
931     def __setitem__(self,i,value):
932 jgs 149 """
933     Sets the i-th model.
934     """
935 jgs 147 if not isinstance(value,Model):
936 gross 728 raise ValueError,"assigned value is not a Model but instance of %s"%(value.__class__.__name__,)
937 jgs 149 for j in range(max(i-len(self.__models)+1,0)):
938     self.__models.append(None)
939 jgs 147 self.__models[i]=value
940    
941     def __len__(self):
942 jgs 149 """
943     Returns the number of models.
944     """
945 jgs 147 return len(self.__models)
946 jgs 121
947 gross 938 def getAllModels(self):
948     """
949     returns a list of all models used in the Simulation including subsimulations
950     """
951     out=[]
952     for m in self.iterModels():
953     if isinstance(m, Simulation):
954     out+=m.getAllModels()
955     else:
956     out.append(m)
957     return list(set(out))
958    
959 gross 950 def checkModels(self, models, hash):
960 gross 938 """
961     returns a list of (model,parameter, target model ) if the the parameter of model
962     is linking to the target_model which is not in list of models.
963     """
964 gross 952 out=self.checkLinkTargets(models, hash + [self])
965 gross 938 for m in self.iterModels():
966     if isinstance(m, Simulation):
967 gross 952 out|=m.checkModels(models, hash)
968 gross 938 else:
969 gross 952 out|=m.checkLinkTargets(models, hash + [self])
970     return set( [ (str(self)+"."+f[0],f[1]) for f in out ] )
971 gross 938
972 jgs 147
973     def getSafeTimeStepSize(self,dt):
974 jgs 149 """
975     Returns a time step size which can safely be used by all models.
976    
977     This is the minimum over the time step sizes of all models.
978     """
979 jgs 147 out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])
980     return out
981 gross 975
982     def setUp(self):
983     """
984     performs the setup for all models
985     """
986     for o in self.iterModels():
987     o.setUp()
988 jgs 147
989     def doInitialization(self):
990 jgs 149 """
991     Initializes all models.
992     """
993 jgs 147 for o in self.iterModels():
994 gross 906 o.doInitialization()
995     def doInitialStep(self):
996     """
997     performs an iteration step in the initialization step for all models
998     """
999 gross 908 iter=0
1000     while not self.terminateInitialIteration():
1001     if iter==0: self.trace("iteration for initialization starts")
1002     iter+=1
1003     self.trace("iteration step %d"%(iter))
1004     for o in self.iterModels():
1005     o.doInitialStep()
1006     if iter>self.MAX_ITER_STEPS:
1007     raise IterationDivergenceError("initial iteration did not converge after %s steps."%iter)
1008     self.trace("Initialization finalized after %s iteration steps."%iter)
1009 gross 906
1010     def doInitialPostprocessing(self):
1011     """
1012     finalises the initialization iteration process for all models.
1013     """
1014     for o in self.iterModels():
1015     o.doInitialPostprocessing()
1016 jgs 147 def finalize(self):
1017 jgs 149 """
1018     Returns True if any of the models is to be finalized.
1019     """
1020 jgs 147 return any([o.finalize() for o in self.iterModels()])
1021 jgs 123
1022 jgs 147 def doFinalization(self):
1023 jgs 149 """
1024 gross 906 finalises the time stepping for all models.
1025 jgs 149 """
1026 jgs 147 for i in self.iterModels(): i.doFinalization()
1027     self.trace("end of time integation.")
1028    
1029     def doStepPreprocessing(self,dt):
1030 jgs 149 """
1031     Initializes the time step for all models.
1032     """
1033 jgs 147 for o in self.iterModels():
1034     o.doStepPreprocessing(dt)
1035    
1036     def terminateIteration(self):
1037 jgs 149 """
1038     Returns True if all iterations for all models are terminated.
1039     """
1040 jgs 147 out=all([o.terminateIteration() for o in self.iterModels()])
1041     return out
1042 gross 906
1043     def terminateInitialIteration(self):
1044     """
1045     Returns True if all initial iterations for all models are terminated.
1046     """
1047     out=all([o.terminateInitialIteration() for o in self.iterModels()])
1048     return out
1049 jgs 123
1050 jgs 147 def doStepPostprocessing(self,dt):
1051 jgs 149 """
1052 gross 906 finalises the iteration process for all models.
1053 jgs 149 """
1054 jgs 147 for o in self.iterModels():
1055     o.doStepPostprocessing(dt)
1056 gross 975 self.time_step+=1
1057     self.time+=dt
1058     self.dt=dt
1059 jgs 147
1060     def doStep(self,dt):
1061     """
1062 jgs 149 Executes the iteration step at a time step for all model::
1063 jgs 147
1064 jgs 149 self.doStepPreprocessing(dt)
1065     while not self.terminateIteration():
1066     for all models:
1067     self.doStep(dt)
1068     self.doStepPostprocessing(dt)
1069 jgs 147 """
1070     self.iter=0
1071     while not self.terminateIteration():
1072 gross 975 if self.iter==0: self.trace("iteration at %d-th time step %e starts"%(self.time_step+1,self.time+dt))
1073 jgs 147 self.iter+=1
1074     self.trace("iteration step %d"%(self.iter))
1075     for o in self.iterModels():
1076     o.doStep(dt)
1077 gross 975 if self.iter>0: self.trace("iteration at %d-th time step %e finalized."%(self.time_step+1,self.time+dt))
1078 jgs 121
1079 gross 975 def run(self,check_pointing=None):
1080 jgs 147 """
1081 jgs 149 Run the simulation by performing essentially::
1082 jgs 123
1083 gross 975 self.setUp()
1084     if not restart:
1085     self.doInitialization()
1086     while not self.terminateInitialIteration(): self.doInitialStep()
1087     self.doInitialPostprocessing()
1088 jgs 149 while not self.finalize():
1089     dt=self.getSafeTimeStepSize()
1090 gross 975 self.doStepPreprocessing(dt_new)
1091     self.doStep(dt_new)
1092     self.doStepPostprocessing(dt_new)
1093 jgs 149 self.doFinalization()
1094 jgs 121
1095 jgs 149 If one of the models in throws a C{FailedTimeStepError} exception a
1096     new time step size is computed through getSafeTimeStepSize() and the
1097     time step is repeated.
1098 jgs 121
1099 jgs 149 If one of the models in throws a C{IterationDivergenceError}
1100     exception the time step size is halved and the time step is repeated.
1101 jgs 121
1102 jgs 149 In both cases the time integration is given up after
1103     C{Simulation.FAILED_TIME_STEPS_MAX} attempts.
1104 jgs 147 """
1105 gross 938 # check the completness of the models:
1106     # first a list of all the models involved in the simulation including subsimulations:
1107     #
1108 gross 950 missing=self.checkModels(self.getAllModels(), [])
1109 gross 938 if len(missing)>0:
1110     msg=""
1111     for l in missing:
1112 gross 952 msg+="\n\t"+str(l[1])+" at "+l[0]
1113 gross 938 raise MissingLink("link targets missing in the Simulation: %s"%msg)
1114     #==============================
1115 gross 975 self.setUp()
1116     if self.time_step < 1:
1117     self.doInitialization()
1118     self.doInitialStep()
1119     self.doInitialPostprocessing()
1120 jgs 147 while not self.finalize():
1121     step_fail_counter=0
1122     iteration_fail_counter=0
1123 gross 975 if self.time_step==0:
1124 gross 980 dt_new=self.getSafeTimeStepSize(self.dt)
1125 gross 836 else:
1126 gross 975 dt_new=min(max(self.getSafeTimeStepSize(self.dt),self.dt/self.MAX_CHANGE_OF_DT),self.dt*self.MAX_CHANGE_OF_DT)
1127     self.trace("%d. time step %e (step size %e.)" % (self.time_step+1,self.time+dt_new,dt_new))
1128 jgs 147 end_of_step=False
1129     while not end_of_step:
1130     end_of_step=True
1131     if not dt_new>0:
1132 gross 975 raise NonPositiveStepSizeError("non-positive step size in step %d"%(self.time_step+1))
1133 jgs 147 try:
1134     self.doStepPreprocessing(dt_new)
1135     self.doStep(dt_new)
1136     self.doStepPostprocessing(dt_new)
1137     except IterationDivergenceError:
1138     dt_new*=0.5
1139     end_of_step=False
1140     iteration_fail_counter+=1
1141     if iteration_fail_counter>self.FAILED_TIME_STEPS_MAX:
1142 gross 836 raise SimulationBreakDownError("reduction of time step to achieve convergence failed after %s steps."%self.FAILED_TIME_STEPS_MAX)
1143     self.trace("Iteration failed. Time step is repeated with new step size %s."%dt_new)
1144 jgs 147 except FailedTimeStepError:
1145 gross 975 dt_new=self.getSafeTimeStepSize(self.dt)
1146 jgs 147 end_of_step=False
1147     step_fail_counter+=1
1148 gross 836 self.trace("Time step is repeated with new time step size %s."%dt_new)
1149 jgs 147 if step_fail_counter>self.FAILED_TIME_STEPS_MAX:
1150 gross 836 raise SimulationBreakDownError("Time integration is given up after %d attempts."%step_fail_counter)
1151 gross 980 if not check_pointing==None:
1152     if check_pointing.doDump():
1153 jgs 147 self.trace("check point is created.")
1154     self.writeXML()
1155     self.doFinalization()
1156 jgs 121
1157 gross 918
1158     def toDom(self, esysxml, node):
1159     """
1160     C{toDom} method of Simulation class.
1161     """
1162     simulation = esysxml.createElement('Simulation')
1163     esysxml.registerLinkableObject(self, simulation)
1164     for rank, sim in enumerate(self.iterModels()):
1165     component = esysxml.createElement('Component')
1166     component.setAttribute('rank', str(rank))
1167     sim.toDom(esysxml, component)
1168     simulation.appendChild(component)
1169     node.appendChild(simulation)
1170    
1171    
1172     def fromDom(cls, esysxml, node):
1173 jgs 147 sims = []
1174 gross 918 for n in node.childNodes:
1175     if isinstance(n, minidom.Text):
1176 jgs 147 continue
1177 gross 918 sims.append(esysxml.getComponent(n))
1178 phornby 1020 sims.sort(_comp)
1179 gross 918 sim=cls([s[1] for s in sims], debug=esysxml.debug)
1180     esysxml.registerLinkableObject(sim, node)
1181     return sim
1182 jgs 121
1183 jgs 147 fromDom = classmethod(fromDom)
1184 jgs 121
1185 gross 918 def _comp(a,b):
1186     if a[0]<a[1]:
1187     return 1
1188     elif a[0]>a[1]:
1189     return -1
1190     else:
1191     return 0
1192 jgs 121
1193 jgs 147 class IterationDivergenceError(Exception):
1194     """
1195 jgs 149 Exception which is thrown if there is no convergence of the iteration
1196     process at a time step.
1197 jgs 121
1198 jgs 149 But there is a chance that a smaller step could help to reach convergence.
1199 jgs 147 """
1200     pass
1201 jgs 121
1202 jgs 147 class FailedTimeStepError(Exception):
1203 jgs 149 """
1204     Exception which is thrown if the time step fails because of a step
1205     size that have been choosen to be too large.
1206     """
1207 jgs 147 pass
1208 jgs 121
1209 jgs 147 class SimulationBreakDownError(Exception):
1210 jgs 149 """
1211     Exception which is thrown if the simulation does not manage to
1212     progress in time.
1213     """
1214 jgs 147 pass
1215 jgs 121
1216 jgs 147 class NonPositiveStepSizeError(Exception):
1217 jgs 149 """
1218     Exception which is thrown if the step size is not positive.
1219     """
1220 jgs 147 pass
1221 jgs 149
1222 gross 938 class MissingLink(Exception):
1223     """
1224     Exception thrown when a link is missing
1225     """
1226     pass
1227    
1228 elspeth 875 class DataSource(object):
1229     """
1230     Class for handling data sources, including local and remote files. This class is under development.
1231     """
1232    
1233 gross 885 def __init__(self, uri="file.ext", fileformat="unknown"):
1234 elspeth 875 self.uri = uri
1235     self.fileformat = fileformat
1236    
1237 gross 918 def toDom(self, esysxml, node):
1238 elspeth 875 """
1239     C{toDom} method of DataSource. Creates a DataSource node and appends it to the
1240 gross 918 current XML esysxml.
1241 elspeth 875 """
1242 gross 918 ds = esysxml.createElement('DataSource')
1243     ds.appendChild(esysxml.createDataNode('URI', self.uri))
1244     ds.appendChild(esysxml.createDataNode('FileFormat', self.fileformat))
1245 elspeth 875 node.appendChild(ds)
1246    
1247 gross 918 def fromDom(cls, esysxml, node):
1248 gross 920 uri= str(node.getElementsByTagName("URI")[0].firstChild.nodeValue.strip())
1249     fileformat= str(node.getElementsByTagName("FileFormat")[0].firstChild.nodeValue.strip())
1250 elspeth 875 ds = cls(uri, fileformat)
1251     return ds
1252    
1253 gross 885 def getLocalFileName(self):
1254     return self.uri
1255    
1256 elspeth 875 fromDom = classmethod(fromDom)
1257 gross 975
1258     class RestartManager(object):
1259     """
1260     A restart manager which does two things: it decides when restart files have created (when doDump returns true) and
1261     manages directories for restart files. The method getNewDumper creates a new directory and returns its name.
1262    
1263     This restart manager will decide to dump restart files if every dump_step calls of doDump or
1264     if more than dump_time since the last dump has elapsed. The restart manager controls two directories for dumping restart data, namely
1265     for the current and previous dump. This way the previous dump can be used for restart in the case the current dump failed.
1266    
1267     @cvar SEC: unit of seconds, for instance for 5*RestartManager.SEC to define 5 seconds.
1268     @cvar MIN: unit of minutes, for instance for 5*RestartManager.MIN to define 5 minutes.
1269     @cvar H: unit of hours, for instance for 5*RestartManager.H to define 5 hours.
1270     @cvar D: unit of days, for instance for 5*RestartManager.D to define 5 days.
1271     """
1272     SEC=1.
1273     MIN=60.
1274     H=360.
1275     D=8640.
1276     def __init__(self,dump_time=1080., dump_step=None, dumper=None):
1277     """
1278     initializes the RestartManager.
1279    
1280     @param dump_time: defines the minimum time interval in SEC between to dumps. If None, time is not used as criterion.
1281     @param dump_step: defines the number of calls of doDump between to dump events. If None, the call counter is not used as criterion.
1282     @param dumper: defines the directory for dumping restart files. Additionally the directories dumper+"_bkp" and dumper+"_bkp2" are used.
1283     if the directory does not exist it is created. If dumper is not present a unique directory within the current
1284     working directory is used.
1285     """
1286     self.__dump_step=dump_time
1287     self.__dump_time=dump_step
1288     self.__counter=0
1289     self.__saveMarker()
1290     if dumper == None:
1291     self.__dumper="restart"+str(os.getpid())
1292     else:
1293     self.__dumper=dumper
1294     self.__dumper_bkp=self.__dumper+"_bkp"
1295     self.__dumper_bkp2=self.__dumper+"_bkp2"
1296     self.__current_dumper=None
1297     def __saveMarker(self):
1298     self.__last_restart_time=time.time()
1299     self.__last_restart_counter=self.__counter
1300     def getCurrentDumper(self):
1301     """
1302     returns the name of the currently used dumper
1303     """
1304     return self.__current_dumper
1305     def doDump(self):
1306     """
1307     returns true the restart should be dumped. use C{getNewDumper} to get the directory name to be used.
1308     """
1309     if self.__dump_step == None:
1310     if self.__dump_step == None:
1311     out = False
1312     else:
1313     out = (self.__dump_step + self.__last_restart_counter) <= self.__counter
1314     else:
1315     if dump_step == None:
1316     out = (self.__last_restart_time + self.__dump_time) <= time.time()
1317     else:
1318     out = ( (self.__dump_step + self.__last_restart_counter) <= self.__counter) \
1319     or ( (self.__last_restart_time + self.__dump_time) <= time.time() )
1320     if out: self.__saveMarker()
1321     self__counter+=1
1322     def getNewDumper(self):
1323     """
1324     creates a new directory to be used for dumping and returns its name.
1325     """
1326     if os.access(self.__dumper_bkp,os.F_OK):
1327     if os.access(self.__dumper_bkp2, os.F_OK):
1328     raise RunTimeError("please remove %s."%self.__dumper_bkp2)
1329     try:
1330     os.rename(self.__dumper_bkp, self.__dumper_bkp2)
1331     except:
1332     self.__current_dumper=self.__dumper
1333     raise RunTimeError("renaming back-up directory %s failed. Use %s for restart."%(self.__dumper_bkp,self.__dumper))
1334     if os.access(self.__dumper,os.F_OK):
1335     if os.access(self.__dumper_bkp, os.F_OK):
1336     raise RunTimeError("please remove %s."%self.__dumper_bkp)
1337     try:
1338     os.rename(self.__dumper, self.__dumper_bkp)
1339     except:
1340     self.__current_dumper=self.__dumper_bkp2
1341     raise RunTimeError("moving directory %s to back-up failed. Use %s for restart."%(self.__dumper,self.__dumper_bkp2))
1342     try:
1343     os.mkdir(self.__dumper)
1344     except:
1345     self.__current_dumper=self.__dumper_bkp
1346     raise RunTimeError("creating a new restart directory %s failed. Use %s for restart."%(self.__dumper,self.__dumper_bkp))
1347     if os.access(self.__dumper_bkp2, os.F_OK): os.rmdir(self.__dumper_bkp2)
1348     return self.getCurrentDumper()
1349    
1350    
1351 jgs 149 # vim: expandtab shiftwidth=4:

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26