/[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 1020 - (hide annotations)
Mon Mar 12 10:12:36 2007 UTC (12 years, 8 months ago) by phornby
File MIME type: text/x-python
File size: 45942 byte(s)
Added explicit destructors to all Exception classes.

Fixed an ifdef in TestCase.cpp

Made the conditional definition of M_PI in LocalOps.h
depend only on M_PI being undefined.

Replace dynamically dimensioned arrays in DataFactory & DataTagged with malloc.

sort() method of list does not take a named argument
(despite the manual's claims to the contary).


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