source: sasview/sansmodels/src/sans/models/BaseComponent.py @ 045be84d

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 045be84d was 045be84d, checked in by Jae Cho <jhjcho@…>, 12 years ago

fixing pylint warnings

  • Property mode set to 100644
File size: 8.6 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        #list of non-fittable parameter
38        self.non_fittable = []
39        ## parameters with orientation
40        self.orientation_params = []
41        ## store dispersity reference
42        self._persistency_dict = {}
43        ## independent parameter name and unit [string]
44        self.input_name = "Q"
45        self.input_unit = "A^{-1}"
46        ## output name and unit  [string]
47        self.output_name = "Intensity"
48        self.output_unit = "cm^{-1}"
49       
50    def __str__(self):
51        """
52        :return: string representatio
53
54        """
55        return self.name
56   
57    def is_fittable(self, par_name):
58        """
59        Check if a given parameter is fittable or not
60       
61        :param par_name: the parameter name to check
62       
63        """
64        return par_name.lower() in self.fixed
65        #For the future
66        #return self.params[str(par_name)].is_fittable()
67   
68    def run(self, x): return NotImplemented
69    def runXY(self, x): return NotImplemented 
70    def calculate_ER(self): return NotImplemented 
71    def calculate_VR(self): return NotImplemented 
72    def evalDistribution(self, qdist):
73        """
74        Evaluate a distribution of q-values.
75       
76        * For 1D, a numpy array is expected as input:
77       
78            evalDistribution(q)
79           
80        where q is a numpy array.
81       
82       
83        * For 2D, a list of numpy arrays are expected: [qx_prime,qy_prime],
84          where 1D arrays,
85       
86        qx_prime = [ qx[0], qx[1], qx[2], ....]
87        and
88        qy_prime = [ qy[0], qy[1], qy[2], ....]
89       
90        Then get
91        q = numpy.sqrt(qx_prime^2+qy_prime^2)
92       
93        that is a qr in 1D array;
94        q = [q[0], q[1], q[2], ....]
95       
96        :Note: Due to 2D speed issue, no anisotropic scattering
97            is supported for python models, thus C-models should have
98             their own evalDistribution methods.
99       
100        The method is then called the following way:
101       
102        evalDistribution(q)
103        where q is a numpy array.
104       
105        :param qdist: ndarray of scalar q-values or list [qx,qy]
106                    where qx,qy are 1D ndarrays
107       
108        """
109        if qdist.__class__.__name__ == 'list':
110            # Check whether we have a list of ndarrays [qx,qy]
111            if len(qdist)!=2 or \
112                qdist[0].__class__.__name__ != 'ndarray' or \
113                qdist[1].__class__.__name__ != 'ndarray':
114                    raise RuntimeError, "evalDistribution expects a list of 2 ndarrays"
115               
116            # Extract qx and qy for code clarity
117            qx = qdist[0]
118            qy = qdist[1]
119           
120            # calculate q_r component for 2D isotropic
121            q = numpy.sqrt(qx**2+qy**2)
122            # vectorize the model function runXY
123            v_model = numpy.vectorize(self.runXY,otypes=[float])
124            # calculate the scattering
125            iq_array = v_model(q)
126
127            return iq_array
128               
129        elif qdist.__class__.__name__ == 'ndarray':
130                # We have a simple 1D distribution of q-values
131                v_model = numpy.vectorize(self.runXY,otypes=[float])
132                iq_array = v_model(qdist)
133
134                return iq_array
135           
136        else:
137            mesg = "evalDistribution is expecting an ndarray of scalar q-values"
138            mesg += " or a list [qx,qy] where qx,qy are 2D ndarrays."
139            raise RuntimeError, mesg
140       
141   
142   
143    def clone(self):
144        """ Returns a new object identical to the current object """
145        obj = copy.deepcopy(self)
146        return self._clone(obj)
147   
148    def _clone(self, obj):
149        """
150        Internal utility function to copy the internal
151        data members to a fresh copy.
152        """
153        obj.params     = copy.deepcopy(self.params)
154        obj.details    = copy.deepcopy(self.details)
155        obj.dispersion = copy.deepcopy(self.dispersion)
156        obj._persistency_dict = copy.deepcopy( self._persistency_dict)
157        return obj
158   
159    def _set_dispersion(self):
160        """
161        model dispersions
162        """ 
163        ##set dispersion from model
164        self.dispersion = {}
165       
166    def getProfile(self):
167        """
168        Get SLD profile
169       
170        : return: (z, beta) where z is a list of depth of the transition points
171                beta is a list of the corresponding SLD values
172        """
173        #Not Implemented
174        return None, None
175           
176    def setParam(self, name, value):
177        """
178        Set the value of a model parameter
179   
180        :param name: name of the parameter
181        :param value: value of the parameter
182       
183        """
184        # Look for dispersion parameters
185        toks = name.split('.')
186        if len(toks)==2:
187            for item in self.dispersion.keys():
188                if item.lower()==toks[0].lower():
189                    for par in self.dispersion[item]:
190                        if par.lower() == toks[1].lower():
191                            self.dispersion[item][par] = value
192                            return
193        else:
194            # Look for standard parameter
195            for item in self.params.keys():
196                if item.lower()==name.lower():
197                    self.params[item] = value
198                    return
199           
200        raise ValueError, "Model does not contain parameter %s" % name
201       
202    def getParam(self, name):
203        """
204        Set the value of a model parameter
205
206        :param name: name of the parameter
207       
208        """
209        # Look for dispersion parameters
210        toks = name.split('.')
211        if len(toks)==2:
212            for item in self.dispersion.keys():
213                if item.lower()==toks[0].lower():
214                    for par in self.dispersion[item]:
215                        if par.lower() == toks[1].lower():
216                            return self.dispersion[item][par]
217        else:
218            # Look for standard parameter
219            for item in self.params.keys():
220                if item.lower()==name.lower():
221                    return self.params[item]
222           
223        raise ValueError, "Model does not contain parameter %s" % name
224     
225    def getParamList(self):
226        """
227        Return a list of all available parameters for the model
228        """ 
229        list = self.params.keys()
230        # WARNING: Extending the list with the dispersion parameters
231        list.extend(self.getDispParamList())
232        return list
233   
234    def getDispParamList(self):
235        """
236        Return a list of all available parameters for the model
237        """ 
238        list = []
239       
240        for item in self.dispersion.keys():
241            for p in self.dispersion[item].keys():
242                if p not in ['type']:
243                    list.append('%s.%s' % (item.lower(), p.lower()))
244                   
245        return list
246   
247    # Old-style methods that are no longer used
248    def setParamWithToken(self, name, value, token, member): return NotImplemented
249    def getParamWithToken(self, name, token, member): return NotImplemented
250    def getParamListWithToken(self, token, member): return NotImplemented
251    def __add__(self, other): raise ValueError, "Model operation are no longer supported"
252    def __sub__(self, other): raise ValueError, "Model operation are no longer supported"
253    def __mul__(self, other): raise ValueError, "Model operation are no longer supported"
254    def __div__(self, other): raise ValueError, "Model operation are no longer supported"
255       
Note: See TracBrowser for help on using the repository browser.