source: sasview/sansmodels/src/sans/models/BaseComponent.py @ 0ab485b

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 0ab485b was f9bf661, checked in by Jae Cho <jhjcho@…>, 15 years ago

updated documents

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