source: sasview/sansmodels/src/sans/models/ModelIO.py @ d292959

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since d292959 was ae3ce4e, checked in by Mathieu Doucet <doucetm@…>, 17 years ago

Moving sansmodels to trunk

  • Property mode set to 100644
File size: 7.2 KB
Line 
1#!/usr/bin/env python
2""" Model IO
3    Class that saves and loads composite models from files
4    The parameters of the models are not set. The loaded
5    model object will have the default parameters for all
6    sub-models.
7
8    @author: Mathieu Doucet / UTK
9    @contact: mathieu.doucet@nist.gov
10"""
11
12import sys
13
14class ModelIO:
15    """ Class to create composite models from file or save a model """
16   
17    def __init__(self, factory):
18        """ Initizalization
19            @param factory: ModelFactory object
20        """
21       
22        ## Factory used to create the right type of component
23        self.factory = factory
24   
25    def modelToXML(self, model):
26        """ Saves XML representation of the component
27            @param model: model to save
28            @param file: name of file to write to (if None, a string is returned)
29        """
30
31        try:
32            # Type
33           
34            repr = "<Component class='%s' name='%s'>\n" \
35                % (model.__class__.__name__, model.name)
36           
37            # Parameters
38           
39            #for p in model.params:
40            #    repr += "  <Param name='%s'>\n" % p
41            #    par_type = ''
42            #    try:
43            #        type_tok = str(type(model.params[p])).split("\'")
44            #        if len(type_tok)>2:
45            #            par_type = type_tok[1]
46            #    except:
47            #        print sys.exc_value
48            #    repr += "    <Type>%s</Type>\n" % par_type
49            #    repr += "    <Value>%s</Value>\n" % model.params[p]
50            #    repr += "  </Param>"
51       
52            # Operation parameters
53            if model.__class__.__name__ in ['AddComponent', 'SubComponent', 
54                                            'MulComponent', 'DivComponent']:
55                repr += "  <operateOn>\n"
56                repr += "    %s" % self.modelToXML(model.operateOn)
57                repr += "  </operateOn>\n"
58               
59            if model.__class__.__name__ == "AddComponent":
60                repr += "  <toAdd>\n"
61                repr += "    %s" % self.modelToXML(model.other)
62                repr += "  </toAdd>\n"
63               
64            if model.__class__.__name__ == "SubComponent":
65                repr += "  <toSub>\n"
66                repr += "    %s" % self.modelToXML(model.other)
67                repr += "  </toSub>\n"
68                   
69            if model.__class__.__name__ == "MulComponent":
70                repr += "  <toMul>\n"
71                repr += "    %s" % self.modelToXML(model.other)
72                repr += "  </toMul>\n"
73               
74            if model.__class__.__name__ == "DivComponent":
75                repr += "  <toDiv>\n"
76                repr += "    %s" % self.modelToXML(model.other)
77                repr += "  </toDiv>\n"
78               
79            repr += "</Component>\n"
80        except:
81            text_out = "ModelIO.save: Error occured while reading info\n  %s" \
82                % sys.exc_value
83            raise ValueError, text_out
84       
85        # Return the XML representation of the model
86        return repr
87       
88    def save(self, model, filename):
89        """ Save the XML representation of a model to a file
90            @param model: XML representation of the model
91            @param filename: the path of the file to write to
92            @return: True if everything went well
93        """
94        file_obj = open(filename,'w')
95        file_obj.write(self.modelToXML(model))
96        file_obj.close()
97        return True
98   
99    def load(self, filename):
100        """ Load a model from a file
101            @param file: file to load
102            @return: a new BaseComponent
103        """
104        # Recurse through XML tree
105        from xml.dom.minidom import parse
106        dom = parse(filename)
107       
108        # Look for Component nodes
109        return self.lookupComponentNodes(dom)
110       
111             
112    def lookupComponentNodes(self, node): 
113        """ Look up a component node among the children of a node
114            @param node: the minidom node to investigate
115            @return: the model object described by the component node, None otherwise
116        """
117        # Look for Component nodes
118        if node.hasChildNodes():
119            for n in node.childNodes:
120                if n.nodeName == "Component":
121                    name = None
122                    type = None
123                    if n.hasAttributes():
124                        # Get the class name & name attribute of the object
125                        for i in range(len(n.attributes)):
126                            attr_name = n.attributes.item(i).name
127                            if attr_name == "class":
128                                type = n.attributes.item(i).nodeValue
129                            elif attr_name == "name":
130                                name = n.attributes.item(i).nodeValue
131                           
132                    # Check that all the information is there
133                    if name == None or type == None:
134                        raise ValueError, \
135                        "Incomplete model description: missing name or class"
136                    else:
137                        # Create an object of the type found
138                        model_object = self.factory.getModel(type)
139                   
140                        # Process other nodes that might be attached
141                        # to this model
142                        self.processComponentNode(n, model_object)
143                       
144                        # Return the object instantiated from the
145                        # first node found
146                        return model_object
147                   
148        return None
149                   
150       
151    def processComponentNode(self, node, model):
152        """ Process an XML 'Component' node in a model file
153            @param node: XML minidom node to process
154            @param model: model object to build from
155        """
156        if node.hasChildNodes():
157            for n in node.childNodes:
158                if n.nodeName == "operateOn":
159                    model.operateOn = self.lookupComponentNodes(n)
160                elif n.nodeName == "toAdd":
161                    model.other = self.lookupComponentNodes(n)
162                elif n.nodeName == "toSub":
163                    model.other = self.lookupComponentNodes(n)
164                elif n.nodeName == "toMul":
165                    model.other = self.lookupComponentNodes(n)
166                elif n.nodeName == "toDiv":
167                    model.other = self.lookupComponentNodes(n)       
168
169# main
170if __name__ == '__main__':
171    from ModelFactory import ModelFactory
172    fac = ModelFactory()
173    cyl = fac.getModel('CylinderModel')
174    sph = fac.getModel('SphereModel')
175    c = cyl+sph
176    io = ModelIO(fac)
177    io.save(c,"myModel.xml")
178    value = c.run(1)
179    print "%s: f(1) = %g" % (c.name, value)
180    loaded = io.load("myModel.xml")
181    #print io.modelToXML(loaded)   
182    value2 = loaded.run(1)
183    print "%s: f(1) = %g" % (c.name, value2)
184    if not value == value2:
185        print "AN ERROR OCCURED"
186     
187# End of file
Note: See TracBrowser for help on using the repository browser.