source: sasview/sansmodels/src/sans/models/BaseComponent.py @ 20905a0

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 20905a0 was 79ac6f8, checked in by Gervaise Alina <gervyh@…>, 15 years ago

working on documentation

  • Property mode set to 100644
File size: 7.8 KB
Line 
1#!/usr/bin/env python
2
3"""
4Provide base functionality for all model components
5"""
6
7# imports   
8import copy
9import numpy
10#TO DO: that about a way to make the parameter
11#is self return if it is fittable or not 
12
13class BaseComponent:
14    """
15    Basic model component
16   
17    Since version 0.5.0, basic operations are no longer supported.
18    """
19
20    def __init__(self):
21        """ Initialization"""
22       
23        ## Name of the model
24        self.name = "BaseComponent"
25       
26        ## Parameters to be accessed by client
27        self.params = {}
28        self.details = {}
29        ## Dictionary used to store the dispersity/averaging
30        #  parameters of dispersed/averaged parameters.
31        self.dispersion = {}
32        # string containing information about the model such as the equation
33        #of the given model, exception or possible use
34        self.description=''
35        #list of parameter that can be fitted
36        self.fixed= []
37        ## parameters with orientation
38        self.orientation_params =[]
39        ## store dispersity reference
40        self._persistency_dict = {}
41           
42    def __str__(self):
43        """
44        :return: string representatio
45
46        """
47        return self.name
48   
49    def is_fittable(self, par_name):
50        """
51        Check if a given parameter is fittable or not
52       
53        :param par_name: the parameter name to check
54       
55        """
56        return par_name.lower() in self.fixed
57        #For the future
58        #return self.params[str(par_name)].is_fittable()
59   
60    def run(self, x): return NotImplemented
61    def runXY(self, x): return NotImplemented 
62    def calculate_ER(self): return NotImplemented 
63    def evalDistribution(self, qdist):
64        """
65        Evaluate a distribution of q-values.
66       
67        * For 1D, a numpy array is expected as input:
68       
69            evalDistribution(q)
70           
71        where q is a numpy array.
72       
73       
74        * For 2D, a list of numpy arrays are expected: [qx_prime,qy_prime],
75          where 1D arrays,
76       
77        qx_prime = [ qx[0], qx[1], qx[2], ....]
78        and
79        qy_prime = [ qy[0], qy[1], qy[2], ....]
80       
81        Then get
82        q = numpy.sqrt(qx_prime^2+qy_prime^2)
83       
84        that is a qr in 1D array;
85        q = [q[0], q[1], q[2], ....]
86       
87        :Note: Due to 2D speed issue, no anisotropic scattering
88            is supported for python models, thus C-models should have
89             their own evalDistribution methods.
90       
91        The method is then called the following way:
92       
93        evalDistribution(q)
94        where q is a numpy array.
95       
96        :param qdist: ndarray of scalar q-values or list [qx,qy]
97                    where qx,qy are 1D ndarrays
98       
99        """
100        if qdist.__class__.__name__ == 'list':
101            # Check whether we have a list of ndarrays [qx,qy]
102            if len(qdist)!=2 or \
103                qdist[0].__class__.__name__ != 'ndarray' or \
104                qdist[1].__class__.__name__ != 'ndarray':
105                    raise RuntimeError, "evalDistribution expects a list of 2 ndarrays"
106               
107            # Extract qx and qy for code clarity
108            qx = qdist[0]
109            qy = qdist[1]
110           
111            # calculate q_r component for 2D isotropic
112            q = numpy.sqrt(qx**2+qy**2)
113            # vectorize the model function runXY
114            v_model = numpy.vectorize(self.runXY,otypes=[float])
115            # calculate the scattering
116            iq_array = v_model(q)
117
118            return iq_array
119               
120        elif qdist.__class__.__name__ == 'ndarray':
121                # We have a simple 1D distribution of q-values
122                v_model = numpy.vectorize(self.runXY,otypes=[float])
123                iq_array = v_model(qdist)
124
125                return iq_array
126           
127        else:
128            mesg = "evalDistribution is expecting an ndarray of scalar q-values"
129            mesg += " or a list [qx,qy] where qx,qy are 2D ndarrays."
130            raise RuntimeError, mesg
131       
132   
133   
134    def clone(self):
135        """ Returns a new object identical to the current object """
136        obj = copy.deepcopy(self)
137        return self._clone(obj)
138   
139    def _clone(self, obj):
140        """
141        Internal utility function to copy the internal
142        data members to a fresh copy.
143        """
144        obj.params     = copy.deepcopy(self.params)
145        obj.details    = copy.deepcopy(self.details)
146        obj.dispersion = copy.deepcopy(self.dispersion)
147        obj._persistency_dict = copy.deepcopy( self._persistency_dict)
148        return obj
149
150    def setParam(self, name, value):
151        """
152        Set the value of a model parameter
153   
154        :param name: name of the parameter
155        :param value: value of the parameter
156       
157        """
158        # Look for dispersion parameters
159        toks = name.split('.')
160        if len(toks)==2:
161            for item in self.dispersion.keys():
162                if item.lower()==toks[0].lower():
163                    for par in self.dispersion[item]:
164                        if par.lower() == toks[1].lower():
165                            self.dispersion[item][par] = value
166                            return
167        else:
168            # Look for standard parameter
169            for item in self.params.keys():
170                if item.lower()==name.lower():
171                    self.params[item] = value
172                    return
173           
174        raise ValueError, "Model does not contain parameter %s" % name
175       
176    def getParam(self, name):
177        """
178        Set the value of a model parameter
179
180        :param name: name of the parameter
181       
182        """
183        # Look for dispersion parameters
184        toks = name.split('.')
185        if len(toks)==2:
186            for item in self.dispersion.keys():
187                if item.lower()==toks[0].lower():
188                    for par in self.dispersion[item]:
189                        if par.lower() == toks[1].lower():
190                            return self.dispersion[item][par]
191        else:
192            # Look for standard parameter
193            for item in self.params.keys():
194                if item.lower()==name.lower():
195                    return self.params[item]
196           
197        raise ValueError, "Model does not contain parameter %s" % name
198     
199    def getParamList(self):
200        """
201        Return a list of all available parameters for the model
202        """ 
203        list = self.params.keys()
204        # WARNING: Extending the list with the dispersion parameters
205        list.extend(self.getDispParamList())
206        return list
207   
208    def getDispParamList(self):
209        """
210        Return a list of all available parameters for the model
211        """ 
212        list = []
213       
214        for item in self.dispersion.keys():
215            for p in self.dispersion[item].keys():
216                if p not in ['type']:
217                    list.append('%s.%s' % (item.lower(), p.lower()))
218                   
219        return list
220   
221    # Old-style methods that are no longer used
222    def setParamWithToken(self, name, value, token, member): return NotImplemented
223    def getParamWithToken(self, name, token, member): return NotImplemented
224    def getParamListWithToken(self, token, member): return NotImplemented
225    def __add__(self, other): raise ValueError, "Model operation are no longer supported"
226    def __sub__(self, other): raise ValueError, "Model operation are no longer supported"
227    def __mul__(self, other): raise ValueError, "Model operation are no longer supported"
228    def __div__(self, other): raise ValueError, "Model operation are no longer supported"
229       
Note: See TracBrowser for help on using the repository browser.