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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 912 by gross, Wed Dec 6 03:29:49 2006 UTC revision 939 by gross, Thu Jan 25 04:23:38 2007 UTC
# Line 27  from sys import stdout Line 27  from sys import stdout
27  import numarray  import numarray
28  import operator  import operator
29  import itertools  import itertools
 # import modellib  temporarily removed!!!  
30    
31  # import the 'set' module if it's not defined (python2.3/2.4 difference)  # import the 'set' module if it's not defined (python2.3/2.4 difference)
32  try:  try:
# Line 37  except NameError: Line 36  except NameError:
36    
37  from xml.dom import minidom  from xml.dom import minidom
38    
 def dataNode(document, tagName, data):  
     """  
     C{dataNode}s are the building blocks of the xml documents constructed in  
     this module.    
       
     @param document: the current xml document  
     @param tagName: the associated xml tag  
     @param data: the values in the tag  
     """  
     t = document.createTextNode(str(data))  
     n = document.createElement(tagName)  
     n.appendChild(t)  
     return n  
   
 def esysDoc():  
     """  
     Global method for creating an instance of an EsysXML document.  
     """  
     doc = minidom.Document()  
     esys = doc.createElement('ESys')  
     doc.appendChild(esys)  
     return doc, esys  
39    
40  def all(seq):  def all(seq):
41      for x in seq:      for x in seq:
# Line 72  def any(seq): Line 49  def any(seq):
49              return True              return True
50      return False      return False
51    
 LinkableObjectRegistry = {}  
   
 def registerLinkableObject(obj_id, o):  
     LinkableObjectRegistry[obj_id] = o  
   
 LinkRegistry = []  
   
 def registerLink(obj_id, l):  
     LinkRegistry.append((obj_id,l))  
   
 def parse(xml):  
     """  
     Generic parse method for EsysXML.  Without this, Links don't work.  
     """  
     global LinkRegistry, LinkableObjectRegistry  
     LinkRegistry = []  
     LinkableObjectRegistry = {}  
   
     doc = minidom.parseString(xml)  
     sim = getComponent(doc.firstChild)  
     for obj_id, link in LinkRegistry:  
         link.target = LinkableObjectRegistry[obj_id]  
   
     return sim  
   
52  def importName(modulename, name):  def importName(modulename, name):
53      """ Import a named object from a module in the context of this function,      """ Import a named object from a module in the context of this function,
54          which means you should use fully qualified module paths.          which means you should use fully qualified module paths.
           
55          Return None on failure.          Return None on failure.
56    
57          This function from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52241          This function from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52241
# Line 112  def importName(modulename, name): Line 63  def importName(modulename, name):
63      except KeyError:      except KeyError:
64          raise ImportError("Could not import %s from %s" % (name, modulename))          raise ImportError("Could not import %s from %s" % (name, modulename))
65    
66  def getComponent(doc):  class ESySXMLParser(object):
     """  
     Used to get components of Simualtions, Models.  
67      """      """
68      for node in doc.childNodes:      parser for ESysXML file
69                """
70          if isinstance(node, minidom.Element):      def __init__(self,xml, debug=False):
71              if node.tagName == 'Simulation':        self.__dom = minidom.parseString(xml)
72                  if node.getAttribute("type") == 'Simulation':        self.__linkable_object_registry= {}
73                      return Simulation.fromDom(node)        self.__link_registry=  []
74              if node.tagName == 'Model':        self.__esys=self.__dom.firstChild
75                  if (node.getAttribute("module")):        self.debug=debug
76                      model_module = node.getAttribute("module")    
77                      model_type = node.getAttribute("type")      def getClassPath(self, node):
78                      return importName(model_module, model_type).fromDom(node)          type = node.getAttribute("type")
79                  else:          if (node.getAttribute("module")):
80                      model_type = node.getAttribute("type")              module = node.getAttribute("module")
81                      model_subclasses = Model.__subclasses__()              return importName(module, type)
82                      for model in model_subclasses:          else:
83                          if model_type == model.__name__:              return importName("__main__", type)
                             return Model.fromDom(node)  
             if node.tagName == 'ParameterSet':  
                 parameter_type = node.getAttribute("type")  
                 return ParameterSet.fromDom(node)  
             raise "Invalid simulation type, %r" % node.getAttribute("type")  
           
84    
85      raise ValueError("No Simulation Found")      def setLinks(self):
86                        for obj_id, link in self.__link_registry:
87                link.target = self.__linkable_object_registry[obj_id]
88    
89        def parse(self):
90           """
91           parser method for EsysXML and returns the list of generating ParameterSets
92           """
93           found=[]
94           for node in self.__esys.childNodes:
95               if isinstance(node, minidom.Element):
96                   if node.tagName == 'Simulation':
97                            found.append(Simulation.fromDom(self, node))
98                   elif node.tagName == 'Model':
99                            found.append(self.getClassPath(node).fromDom(self, node))
100                   elif node.tagName == 'ParameterSet':
101                            found.append(self.getClassPath(node).fromDom(self, node))
102                   else:
103                      raise "Invalid type, %r" % node.getAttribute("type")
104           self.setLinks()
105           return found
106    
107        def registerLink(self,obj_id, link):
108            self.__link_registry.append((int(obj_id),link))
109    
110        def registerLinkableObject(self,obj, node):
111            id_str=node.getAttribute('id').strip()
112            if len(id_str)>0:
113               id=int(id_str)
114               if self.__linkable_object_registry.has_key(id):
115                   raise ValueError("Object id %s already exists."%id)
116               else:
117                   self.__linkable_object_registry[id]=obj
118    
119        def getComponent(self, node):
120           """
121           returns a single component + rank from a simulation
122           parser method for EsysXML and returns the list of generating ParameterSets
123           """
124           rank  = int(node.getAttribute("rank"))
125           for n in node.childNodes:
126               if isinstance(n, minidom.Element):
127                   if n.tagName == 'Simulation':
128                            return (rank, Simulation.fromDom(self, n))
129                   elif n.tagName == 'Model':
130                            return (rank, self.getClassPath(n).fromDom(self, n))
131                   elif n.tagName == 'ParameterSet':
132                            return (rank, self.getClassPath(n).fromDom(self, n))
133                   else:
134                     raise ValueError("illegal component type %s"%n.tagName)
135           raise ValueError("cannot resolve Component")
136    
137    class ESySXMLCreator(object):
138        """
139        creates an XML Dom representation
140        """
141        def __init__(self):
142           self.__dom=minidom.Document()
143           self.__esys =self.__dom.createElement('ESys')
144           self.__dom.appendChild(self.__esys)
145           self.__linkable_object_registry={}
146           self.__number_sequence = itertools.count(100)
147        def getRoot(self):
148           return self.__esys
149        def createElement(self,name):
150          return self.__dom.createElement(name)
151        def createTextNode(self,name):
152          return self.__dom.createTextNode(name)
153        def getElementById(self,name):
154          return self.__dom.getElementById(name)
155        def createDataNode(self, tagName, data):
156              """
157              C{createDataNode}s are the building blocks of the xml documents constructed in
158              this module.  
159        
160              @param tagName: the associated xml tag
161              @param data: the values in the tag
162              """
163              n = self.createElement(tagName)
164              n.appendChild(self.createTextNode(str(data)))
165              return n
166        def getLinkableObjectId(self, obj):
167            for id, o in self.__linkable_object_registry.items():
168                if o == obj: return id
169            id =self.__number_sequence.next()
170            self.__linkable_object_registry[id]=obj
171            return id
172            
173        def registerLinkableObject(self, obj, node):
174            """
175            returns a unique object id for object obj
176            """
177            id=self.getLinkableObjectId(obj)
178            node.setAttribute('id',str(id))
179            node.setIdAttribute("id")
180    
181        def includeTargets(self):
182            target_written=True
183            while target_written:
184                targetsList =self.__dom.getElementsByTagName('Target')
185                target_written=False
186                for element in targetsList:
187                   targetId = int(element.firstChild.nodeValue.strip())
188                   if self.getElementById(str(targetId)): continue
189                   targetObj = self.__linkable_object_registry[targetId]
190                   targetObj.toDom(self, self.__esys)
191                   target_written=True
192    
193        def toprettyxml(self):
194            self.includeTargets()
195            return self.__dom.toprettyxml()
196    
197  class Link:  class Link:
198      """      """
199      A Link makes an attribute of an object callable::      A Link makes an attribute of an object callable::
# Line 162  class Link: Line 214  class Link:
214          self.attribute = None          self.attribute = None
215          self.setAttributeName(attribute)          self.setAttributeName(attribute)
216    
217        def getTarget(self):
218            """
219            returns the target
220            """
221            return self.target
222      def getAttributeName(self):      def getAttributeName(self):
223          """          """
224          returns the name of the attribute the link is pointing to          returns the name of the attribute the link is pointing to
# Line 212  class Link: Line 269  class Link:
269          else:          else:
270              return out              return out
271    
272      def toDom(self, document, node):      def toDom(self, esysxml, node):
273          """          """
274          C{toDom} method of Link. Creates a Link node and appends it to the          C{toDom} method of Link. Creates a Link node and appends it to the
275      current XML document.      current XML esysxml.
276          """          """
277          link = document.createElement('Link')          link = esysxml.createElement('Link')
278          assert (self.target != None), ("Target was none, name was %r" % self.attribute)          assert (self.target != None), ("Target was none, name was %r" % self.attribute)
279          link.appendChild(dataNode(document, 'Target', self.target.id))          link.appendChild(esysxml.createDataNode('Target', esysxml.getLinkableObjectId(self.target)))
280          # this use of id will not work for purposes of being able to retrieve the intended          # this use of id will not work for purposes of being able to retrieve the intended
281          # target from the xml later. I need a better unique identifier.          # target from the xml later. I need a better unique identifier.
282          assert self.attribute, "You can't xmlify a Link without a target attribute"          assert self.attribute, "You can't xmlify a Link without a target attribute"
283          link.appendChild(dataNode(document, 'Attribute', self.attribute))          link.appendChild(esysxml.createDataNode('Attribute', self.attribute))
284          node.appendChild(link)          node.appendChild(link)
285    
286      def fromDom(cls, doc):      def fromDom(cls, esysxml, node):
287          targetid = doc.getElementsByTagName("Target")[0].firstChild.nodeValue.strip()          targetid = int(node.getElementsByTagName("Target")[0].firstChild.nodeValue.strip())
288          attribute = doc.getElementsByTagName("Attribute")[0].firstChild.nodeValue.strip()          attribute =str(node.getElementsByTagName("Attribute")[0].firstChild.nodeValue.strip())
289          l = cls(None, attribute)          l = cls(None, attribute)
290          registerLink(targetid, l)          esysxml.registerLink(targetid, l)
291          return l          return l
292    
293      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
294            
     def writeXML(self,ostream=stdout):  
         """  
         Writes an XML representation of self to the output stream ostream.  
         If ostream is nor present the standart output stream is used.  If  
         esysheader==True the esys XML header is written  
         """  
         print 'I got to the Link writeXML method'  
         document, rootnode = esysDoc()  
         self.toDom(document, rootnode)  
   
         ostream.write(document.toprettyxml())  
   
295  class LinkableObject(object):  class LinkableObject(object):
296      """      """
297      An object that allows to link its attributes to attributes of other objects      An object that allows to link its attributes to attributes of other objects
# Line 265  class LinkableObject(object): Line 310  class LinkableObject(object):
310      the return value of the call.      the return value of the call.
311      """      """
312        
     number_sequence = itertools.count(100)  
313            
314      def __init__(self, debug=False):      def __init__(self, id = None, debug=False):
315          """          """
316      Initializes LinkableObject so that we can operate on Links      Initializes LinkableObject so that we can operate on Links
317      """      """
318          self.debug = debug          self.debug = debug
319          self.__linked_attributes={}          self.__linked_attributes={}
320          self.id = self.number_sequence.next()          
         registerLinkableObject(self.id, self)  
   
321      def trace(self, msg):      def trace(self, msg):
322          """          """
323      If debugging is on, print the message, otherwise do nothing      If debugging is on, print the message, otherwise do nothing
# Line 466  class ParameterSet(LinkableObject): Line 508  class ParameterSet(LinkableObject):
508          except:          except:
509              pass              pass
510    
511      def toDom(self, document, node):      def toDom(self, esysxml, node):
512          """          """
513      C{toDom} method of ParameterSet class.      C{toDom} method of Model class
514      """      """
515          pset = document.createElement('ParameterSet')          pset = esysxml.createElement('ParameterSet')
516            pset.setAttribute('type', self.__class__.__name__)
517            pset.setAttribute('module', self.__class__.__module__)
518            esysxml.registerLinkableObject(self, pset)
519            self._parametersToDom(esysxml, pset)
520          node.appendChild(pset)          node.appendChild(pset)
         self._parametersToDom(document, pset)  
521    
522      def _parametersToDom(self, document, node):      def _parametersToDom(self, esysxml, node):
         node.setAttribute('id', str(self.id))  
         node.setIdAttribute("id")  
523          for name,value in self:          for name,value in self:
524              param = document.createElement('Parameter')              # convert list to numarray when possible:
525              param.setAttribute('type', value.__class__.__name__)              if isinstance (value, list):
526                    elem_type=-1
527                    for i in value:
528                        if isinstance(i, bool):
529                            elem_type = max(elem_type,0)
530                        if isinstance(i, int) and not isinstance(i, bool):
531                            elem_type = max(elem_type,1)
532                        if isinstance(i, float):
533                            elem_type = max(elem_type,2)
534                    if elem_type == 0: value = numarray.array(value,numarray.Bool)
535                    if elem_type == 1: value = numarray.array(value,numarray.Int)
536                    if elem_type == 2: value = numarray.array(value,numarray.Float)
537    
538              param.appendChild(dataNode(document, 'Name', name))              param = esysxml.createElement('Parameter')
539                param.setAttribute('type', value.__class__.__name__)
540    
541              val = document.createElement('Value')              param.appendChild(esysxml.createDataNode('Name', name))
542    
543                val = esysxml.createElement('Value')
544              if isinstance(value,(ParameterSet,Link,DataSource)):              if isinstance(value,(ParameterSet,Link,DataSource)):
545                  value.toDom(document, val)                  value.toDom(esysxml, val)
546                  param.appendChild(val)                  param.appendChild(val)
547              elif isinstance(value, numarray.NumArray):              elif isinstance(value, numarray.NumArray):
548                  shape = value.getshape()                  shape = value.getshape()
# Line 498  class ParameterSet(LinkableObject): Line 554  class ParameterSet(LinkableObject):
554                      shape = str(shape)                      shape = str(shape)
555    
556                  arraytype = value.type()                  arraytype = value.type()
557                  numarrayElement = document.createElement('NumArray')                  if isinstance(arraytype, numarray.BooleanType):
558                  numarrayElement.appendChild(dataNode(document, 'ArrayType', str(arraytype)))                        arraytype_str="Bool"
559                  numarrayElement.appendChild(dataNode(document, 'Shape', shape))                  elif isinstance(arraytype, numarray.IntegralType):
560                  numarrayElement.appendChild(dataNode(document, 'Data', ' '.join(                        arraytype_str="Int"
561                    elif isinstance(arraytype, numarray.FloatingType):
562                          arraytype_str="Float"
563                    elif isinstance(arraytype, numarray.ComplexType):
564                          arraytype_str="Complex"
565                    else:
566                          arraytype_str=str(arraytype)
567                    numarrayElement = esysxml.createElement('NumArray')
568                    numarrayElement.appendChild(esysxml.createDataNode('ArrayType', arraytype_str))
569                    numarrayElement.appendChild(esysxml.createDataNode('Shape', shape))
570                    numarrayElement.appendChild(esysxml.createDataNode('Data', ' '.join(
571                      [str(x) for x in numarray.reshape(value, size)])))                      [str(x) for x in numarray.reshape(value, size)])))
572                  val.appendChild(numarrayElement)                  val.appendChild(numarrayElement)
573                  param.appendChild(val)                  param.appendChild(val)
574              elif isinstance (value, list):              elif isinstance(value, list):
575                  param.appendChild(dataNode(document, 'Value', ' '.join(                  param.appendChild(esysxml.createDataNode('Value', ' '.join([str(x) for x in value]) ))
576                      [str(x) for x in value])              elif isinstance(value, (str, bool, int, float, type(None))):
577                  ))                  param.appendChild(esysxml.createDataNode('Value', str(value)))
578                elif isinstance(value, dict):
579                     dic = esysxml.createElement('dictionary')
580                     if len(value.keys())>0:
581                         dic.setAttribute('key_type', value.keys()[0].__class__.__name__)
582                         dic.setAttribute('value_type', value[value.keys()[0]].__class__.__name__)
583                     for k,v in value.items():
584                        i=esysxml.createElement('item')
585                        i.appendChild(esysxml.createDataNode('key', k))
586                        i.appendChild(esysxml.createDataNode('value', v))
587                        dic.appendChild(i)
588                     param.appendChild(dic)
589              else:              else:
590                  param.appendChild(dataNode(document, 'Value', str(value)))                  print value
591                    raise ValueError("cannot serialize %s type to XML."%str(value.__class__))
592    
593              node.appendChild(param)              node.appendChild(param)
594    
595      def fromDom(cls, doc):      def fromDom(cls, esysxml, node):
   
596          # Define a host of helper functions to assist us.          # Define a host of helper functions to assist us.
597          def _children(node):          def _children(node):
598              """              """
# Line 530  class ParameterSet(LinkableObject): Line 607  class ParameterSet(LinkableObject):
607                      ret.append(x)                      ret.append(x)
608              return ret              return ret
609    
610          def _floatfromValue(doc):          def _floatfromValue(esysxml, node):
611              return float(doc.nodeValue.strip())              return float(node.nodeValue.strip())
612    
613          def _stringfromValue(doc):          def _stringfromValue(esysxml, node):
614              return str(doc.nodeValue.strip())              return str(node.nodeValue.strip())
615                
616          def _intfromValue(doc):          def _intfromValue(esysxml, node):
617              return int(doc.nodeValue.strip())              return int(node.nodeValue.strip())
618    
619          def _boolfromValue(doc):          def _boolfromValue(esysxml, node):
620              return _boolfromstring(doc.nodeValue.strip())              return _boolfromstring(node.nodeValue.strip())
621    
622          def _nonefromValue(doc):          def _nonefromValue(esysxml, node):
623              return None              return None
624    
625          def _numarrayfromValue(doc):          def _numarrayfromValue(esysxml, node):
626              for node in _children(doc):              for node in _children(node):
627                  if node.tagName == 'ArrayType':                  if node.tagName == 'ArrayType':
628                      arraytype = node.firstChild.nodeValue.strip()                      arraytype = node.firstChild.nodeValue.strip()
629                  if node.tagName == 'Shape':                  if node.tagName == 'Shape':
# Line 558  class ParameterSet(LinkableObject): Line 635  class ParameterSet(LinkableObject):
635              return numarray.reshape(numarray.array(data, type=getattr(numarray, arraytype)),              return numarray.reshape(numarray.array(data, type=getattr(numarray, arraytype)),
636                                      shape)                                      shape)
637                
638          def _listfromValue(doc):          def _listfromValue(esysxml, node):
639              return [_boolfromstring(x) for x in doc.nodeValue.split()]              return [x for x in node.nodeValue.split()]
   
640    
641          def _boolfromstring(s):          def _boolfromstring(s):
642              if s == 'True':              if s == 'True':
# Line 582  class ParameterSet(LinkableObject): Line 658  class ParameterSet(LinkableObject):
658                      "NoneType":_nonefromValue,                      "NoneType":_nonefromValue,
659                      }                      }
660    
 #        print doc.toxml()  
   
661          parameters = {}          parameters = {}
662          for node in _children(doc):          for n in _children(node):
663              ptype = node.getAttribute("type")              ptype = n.getAttribute("type")
664                if not ptypemap.has_key(ptype):
665                   raise KeyError("cannot handle parameter type %s."%ptype)
666    
667              pname = pvalue = None              pname = pvalue = None
668              for childnode in _children(node):              for childnode in _children(n):
   
669                  if childnode.tagName == "Name":                  if childnode.tagName == "Name":
670                      pname = childnode.firstChild.nodeValue.strip()                      pname = childnode.firstChild.nodeValue.strip()
671    
672                  if childnode.tagName == "Value":                  if childnode.tagName == "Value":
673                      nodes = _children(childnode)                      nodes = _children(childnode)
674                  #    if ptype == 'NumArray':                      pvalue = ptypemap[ptype](esysxml, nodes[0])
                  #       pvalue = _numarrayfromValue(nodes)  
                  #   else:  
                     pvalue = ptypemap[ptype](nodes[0])  
675    
676              parameters[pname] = pvalue              parameters[pname] = pvalue
677    
678          # Create the instance of ParameterSet          # Create the instance of ParameterSet
679          o = cls()          o = cls(debug=esysxml.debug)
680          o.declareParameters(parameters)          o.declareParameters(parameters)
681          registerLinkableObject(doc.getAttribute("id"), o)          esysxml.registerLinkableObject(o, node)
682          return o          return o
683            
684      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
685        
686      def writeXML(self,ostream=stdout):      def writeXML(self,ostream=stdout):
687          """          """
688      Writes the object as an XML object into an output stream.      Writes the object as an XML object into an output stream.
689      """      """
690          # ParameterSet(d) with d[Name]=Value          esysxml=ESySXMLCreator()
691          document, node = esysDoc()          self.toDom(esysxml, esysxml.getRoot())
692          self.toDom(document, node)          ostream.write(esysxml.toprettyxml())
693          ostream.write(document.toprettyxml())      
   
694  class Model(ParameterSet):  class Model(ParameterSet):
695      """      """
696      A Model object represents a processess marching over time until a      A Model object represents a processess marching over time until a
# Line 646  class Model(ParameterSet): Line 717  class Model(ParameterSet):
717    
718      UNDEF_DT=1.e300      UNDEF_DT=1.e300
719    
720      def __init__(self,parameters=[],**kwarg):      def __init__(self,parameters=[],**kwargs):
721          """          """
722      Creates a model.      Creates a model.
723    
724          Just calls the parent constructor.          Just calls the parent constructor.
725          """          """
726          ParameterSet.__init__(self, parameters=parameters,**kwarg)          ParameterSet.__init__(self, parameters=parameters,**kwargs)
727    
728      def __str__(self):      def __str__(self):
729         return "<%s %d>"%(self.__class__.__name__,id(self))         return "<%s %d>"%(self.__class__.__name__,id(self))
730    
     def toDom(self, document, node):  
         """  
     C{toDom} method of Model class  
     """  
         pset = document.createElement('Model')  
         pset.setAttribute('type', self.__class__.__name__)  
         if not self.__class__.__module__.startswith('esys.escript'):  
             pset.setAttribute('module', self.__class__.__module__)  
         node.appendChild(pset)  
         self._parametersToDom(document, pset)  
731    
732      def doInitialization(self):      def doInitialization(self):
733          """          """
# Line 757  class Model(ParameterSet): Line 818  class Model(ParameterSet):
818          This function may be overwritten.          This function may be overwritten.
819      """      """
820          pass          pass
       
     def writeXML(self, ostream=stdout):  
         document, node = esysDoc()  
         self.toDom(document, node)  
         ostream.write(document.toprettyxml())  
       
821    
822        def toDom(self, esysxml, node):
823            """
824        C{toDom} method of Model class
825        """
826            pset = esysxml.createElement('Model')
827            pset.setAttribute('type', self.__class__.__name__)
828            pset.setAttribute('module', self.__class__.__module__)
829            esysxml.registerLinkableObject(self, pset)
830            node.appendChild(pset)
831            self._parametersToDom(esysxml, pset)
832        
833  class Simulation(Model):  class Simulation(Model):
834      """      """
835      A Simulation object is special Model which runs a sequence of Models.      A Simulation object is special Model which runs a sequence of Models.
# Line 782  class Simulation(Model): Line 848  class Simulation(Model):
848          """          """
849      Initiates a simulation from a list of models.      Initiates a simulation from a list of models.
850      """      """
851          Model.__init__(self, **kwargs)          super(Simulation, self).__init__(**kwargs)
852            for m in models:
853                if not isinstance(m, Model):
854                     raise TypeError("%s is not a subclass of Model."%m)
855          self.__models=[]          self.__models=[]
           
856          for i in range(len(models)):          for i in range(len(models)):
857              self[i] = models[i]              self[i] = models[i]
858                            
# Line 829  class Simulation(Model): Line 897  class Simulation(Model):
897      """      """
898          return len(self.__models)          return len(self.__models)
899    
900      def toDom(self, document, node):      def getAllModels(self):
901          """          """
902      C{toDom} method of Simulation class.          returns a list of all models used in the Simulation including subsimulations
903      """          """
904          simulation = document.createElement('Simulation')          out=[]
905          simulation.setAttribute('type', self.__class__.__name__)          for m in self.iterModels():
906                if isinstance(m, Simulation):
907          for rank, sim in enumerate(self.iterModels()):                 out+=m.getAllModels()
908              component = document.createElement('Component')              else:
909              component.setAttribute('rank', str(rank))                 out.append(m)
910            return list(set(out))
             sim.toDom(document, component)  
   
             simulation.appendChild(component)  
   
         node.appendChild(simulation)  
911    
912      def writeXML(self,ostream=stdout):      def checkModelLinks(self, models):
913          """          """
914      Writes the object as an XML object into an output stream.          returns a list of (model,parameter, target model ) if the the parameter of model
915      """          is linking to the target_model which is not in list of models.
916          document, rootnode = esysDoc()          """
917          self.toDom(document, rootnode)          out=[]
918          targetsList = document.getElementsByTagName('Target')          for m in self.iterModels():
919                        if isinstance(m, Simulation):
920          for element in targetsList:                 out+=[ (m,) + f for f in  m.checkModelLinks(models) ]
921              targetId = int(element.firstChild.nodeValue.strip())              else:
922              if document.getElementById(str(targetId)):                for p in m:
923                  continue                   if isinstance(p[1], Link):
924              targetObj = LinkableObjectRegistry[targetId]                      l_m=p[1].getTarget()
925              targetObj.toDom(document, rootnode)                      if isinstance(l_m, Model) and not l_m in models: out.append( (m,p[0],l_m) )
926          ostream.write(document.toprettyxml())          return out
927    
928            
929      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
930          """          """
# Line 986  class Simulation(Model): Line 1050  class Simulation(Model):
1050          In both cases the time integration is given up after          In both cases the time integration is given up after
1051      C{Simulation.FAILED_TIME_STEPS_MAX} attempts.      C{Simulation.FAILED_TIME_STEPS_MAX} attempts.
1052          """          """
1053            # check the completness of the models:
1054            # first a list of all the models involved in the simulation including subsimulations:
1055            #
1056            missing=self.checkModelLinks(self.getAllModels())
1057            if len(missing)>0:
1058                msg=""
1059                for l in missing:
1060                     msg+="\n\t"+str(l[-1])+" at "+str(self)
1061                     for i in xrange(len(l)-1): msg+="."+str(l[i])
1062                raise MissingLink("link targets missing in the Simulation: %s"%msg)
1063            #==============================
1064          self.doInitialization()          self.doInitialization()
1065          self.doInitialStep()          self.doInitialStep()
1066          self.doInitialPostprocessing()          self.doInitialPostprocessing()
# Line 1028  class Simulation(Model): Line 1103  class Simulation(Model):
1103                      self.writeXML()                      self.writeXML()
1104          self.doFinalization()          self.doFinalization()
1105    
     def fromDom(cls, doc):  
         sims = []  
         for node in doc.childNodes:  
             if isinstance(node, minidom.Text):  
                 continue  
1106    
1107              sims.append(getComponent(node))      def toDom(self, esysxml, node):
1108            """
1109        C{toDom} method of Simulation class.
1110        """
1111            simulation = esysxml.createElement('Simulation')
1112            esysxml.registerLinkableObject(self, simulation)
1113            for rank, sim in enumerate(self.iterModels()):
1114                component = esysxml.createElement('Component')
1115                component.setAttribute('rank', str(rank))
1116                sim.toDom(esysxml, component)
1117                simulation.appendChild(component)
1118            node.appendChild(simulation)
1119    
1120    
1121          return cls(sims)      def fromDom(cls, esysxml, node):
1122            sims = []
1123            for n in node.childNodes:
1124                if isinstance(n, minidom.Text):
1125                    continue
1126                sims.append(esysxml.getComponent(n))
1127            sims.sort(cmp=_comp)
1128            sim=cls([s[1] for s in sims], debug=esysxml.debug)
1129            esysxml.registerLinkableObject(sim, node)
1130            return sim
1131    
1132      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
1133    
1134    def _comp(a,b):
1135        if a[0]<a[1]:
1136          return 1
1137        elif a[0]>a[1]:
1138          return -1
1139        else:
1140          return 0
1141    
1142  class IterationDivergenceError(Exception):  class IterationDivergenceError(Exception):
1143      """      """
# Line 1070  class NonPositiveStepSizeError(Exception Line 1168  class NonPositiveStepSizeError(Exception
1168      """      """
1169      pass      pass
1170    
1171    class MissingLink(Exception):
1172        """
1173        Exception thrown when a link is missing
1174        """
1175        pass
1176    
1177  class DataSource(object):  class DataSource(object):
1178      """      """
1179      Class for handling data sources, including local and remote files. This class is under development.      Class for handling data sources, including local and remote files. This class is under development.
# Line 1079  class DataSource(object): Line 1183  class DataSource(object):
1183          self.uri = uri          self.uri = uri
1184          self.fileformat = fileformat          self.fileformat = fileformat
1185    
1186      def toDom(self, document, node):      def toDom(self, esysxml, node):
1187          """          """
1188          C{toDom} method of DataSource. Creates a DataSource node and appends it to the          C{toDom} method of DataSource. Creates a DataSource node and appends it to the
1189      current XML document.      current XML esysxml.
1190          """          """
1191          ds = document.createElement('DataSource')          ds = esysxml.createElement('DataSource')
1192          ds.appendChild(dataNode(document, 'URI', self.uri))          ds.appendChild(esysxml.createDataNode('URI', self.uri))
1193          ds.appendChild(dataNode(document, 'FileFormat', self.fileformat))          ds.appendChild(esysxml.createDataNode('FileFormat', self.fileformat))
1194          node.appendChild(ds)          node.appendChild(ds)
1195    
1196      def fromDom(cls, doc):      def fromDom(cls, esysxml, node):
1197          uri= doc.getElementsByTagName("URI")[0].firstChild.nodeValue.strip()          uri= str(node.getElementsByTagName("URI")[0].firstChild.nodeValue.strip())
1198          fileformat= doc.getElementsByTagName("FileFormat")[0].firstChild.nodeValue.strip()          fileformat= str(node.getElementsByTagName("FileFormat")[0].firstChild.nodeValue.strip())
1199          ds = cls(uri, fileformat)          ds = cls(uri, fileformat)
1200          return ds          return ds
1201    

Legend:
Removed from v.912  
changed lines
  Added in v.939

  ViewVC Help
Powered by ViewVC 1.1.26