source: sasview/sansmodels/src/sans/models/SphereExpShellModel.py @ 4628e31

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 4628e31 was 85bb870, checked in by Jae Cho <jhjcho@…>, 14 years ago

minor correcions of orientational order,etc

  • Property mode set to 100644
File size: 10.5 KB
Line 
1   
2from sans.models.BaseComponent import BaseComponent
3from sans.models.OnionModel import OnionModel
4import copy
5max_nshells = 10
6class SphereExpShellModel(BaseComponent):
7    """
8    This multi-model is based on CoreMultiShellModel with exponential func shells and provides the capability
9    of changing the number of shells between 1 and 10.
10    """
11    def __init__(self, n_shells=1):
12        BaseComponent.__init__(self)
13        """
14        :param n_shells: number of shells in the model, assumes 1<= n_shells <=10.
15        """
16
17        ## Setting  model name model description
18        self.description=""
19        model = OnionModel()
20        self.model = model
21        self.name = "SphereExpShellModel"
22        self.description=model.description
23        self.n_shells = n_shells
24        ## Define parameters
25        self.params = {}
26
27        ## Parameter details [units, min, max]
28        self.details = {}
29       
30        ## dispersion
31        self._set_dispersion()
32        ## Define parameters
33        self._set_params()
34       
35        ## Parameter details [units, min, max]
36        self._set_details()
37       
38        #list of parameter that can be fitted
39        self._set_fixed_params() 
40        self.model.params['n_shells'] = self.n_shells
41        ## functional multiplicity info of the model
42        # [int(maximum no. of functionality),"str(Titl),
43        # [str(name of function0),...], [str(x-asix name of sld),...]]
44        self.multiplicity_info = [max_nshells,"No. of Shells:",[],['Radius']]
45
46        ## parameters with orientation: can be removed since there is no orientational params
47        for item in self.model.orientation_params:
48            self.orientation_params.append(item)
49        self.getProfile()       
50    def _clone(self, obj):
51        """
52        Internal utility function to copy the internal
53        data members to a fresh copy.
54        """
55        obj.params     = copy.deepcopy(self.params)
56        obj.description     = copy.deepcopy(self.description)
57        obj.details    = copy.deepcopy(self.details)
58        obj.dispersion = copy.deepcopy(self.dispersion)
59        obj.model  = self.model.clone()
60
61        return obj
62   
63   
64    def _set_dispersion(self):
65        """
66        model dispersions
67        """ 
68        ##set dispersion from model
69        for name , value in self.model.dispersion.iteritems():   
70             
71            nshell = 0
72            if name.split('_')[0] == 'thick':
73                while nshell<self.n_shells:
74                    nshell += 1
75                    if name.split('_')[1] == 'shell%s' % str(nshell):
76                        self.dispersion[name]= value
77                    else: 
78                        continue
79            else:
80                self.dispersion[name]= value
81                   
82
83    def _set_params(self):
84        """
85        Concatenate the parameters of the model to create
86        this model parameters
87        """
88        # rearrange the parameters for the given # of shells
89        for name , value in self.model.params.iteritems():
90            nshell = 0
91            pos = len(name.split('_'))-1
92            if name.split('_')[0] == 'func':
93                continue
94            elif name.split('_')[pos][0:5] == 'shell':
95                    while nshell<self.n_shells:
96                        nshell += 1
97                        if name.split('_')[pos] == 'shell%s' % str(nshell):
98                            self.params[name]= value
99                            continue
100            else:
101                self.params[name]= value
102               
103        self.model.params['n_shells'] = self.n_shells   
104
105        # set constrained values for the original model params
106        self._set_xtra_model_param()       
107 
108    def _set_details(self):
109        """
110        Concatenate details of the original model to create
111        this model details
112        """
113        for name ,detail in self.model.details.iteritems():
114            if name in self.params.iterkeys():
115                self.details[name]= detail
116           
117   
118    def _set_xtra_model_param(self):
119        """
120        Set params of original model that are hidden from this model
121        """
122        # look for the model parameters that are not in param list
123        for key in self.model.params.iterkeys():
124            if key not in self.params.keys():
125                if  key.split('_')[0] == 'thick':
126                    self.model.setParam(key, 0)
127                    continue
128                if  key.split('_')[0] == 'A':
129                    self.model.setParam(key, 0)
130                    continue
131                if  key.split('_')[0] == 'func':
132                    self.model.setParam(key, 2)
133                    continue
134                for nshell in range(self.n_shells,max_nshells):
135                    if key.split('_')[1] == 'sld_in_shell%s' % str(nshell+1):
136                        try:
137                            value = self.model.params['sld_solv']
138                            self.model.setParam(key, value)
139                        except: pass
140    def getProfile(self):
141        """
142        Get SLD profile
143       
144        : return: (r, beta) where r is a list of radius of the transition points
145                beta is a list of the corresponding SLD values
146        """
147        # max_pts for each shells
148        max_pts = 10
149        r = []
150        beta = []
151        # for core at r=0
152        r.append(0)
153        beta.append(self.params['sld_core0'])
154        # for core at r=rad_core
155        r.append(self.params['rad_core0'])
156        beta.append(self.params['sld_core0'])
157       
158        # for shells
159        for n in range(1,self.n_shells+1):
160            # Left side of each shells
161            r0 = r[len(r)-1]           
162            r.append(r0)
163            beta.append(self.params['sld_in_shell%s'% str(n)])
164           
165            A = self.params['A_shell%s'% str(n)]
166            from math import fabs
167            if fabs(A) <1.0e-16:
168                # Right side of each shells
169                r0 += self.params['thick_shell%s'% str(n)]
170                r.append(r0)
171                beta.append(self.params['sld_in_shell%s'% str(n)])
172            else:
173                from math import exp
174                rn = r0
175                for n_sub in range(0,max_pts):
176                    # Right side of each sub_shells
177                    rn += self.params['thick_shell%s'% str(n)]/10.0
178                    r.append(rn)
179                    slope = (self.params['sld_out_shell%s'% str(n)] \
180                                        -self.params['sld_in_shell%s'% str(n)]) \
181                                        /(exp(self.params['A_shell%s'% str(n)])-1)
182                    const = (self.params['sld_in_shell%s'% str(n)]-slope)
183                    beta_n = slope*exp((self.params['A_shell%s'% str(n)]*(rn-r0) \
184                                        /self.params['thick_shell%s'% str(n)])) + const
185                    beta.append(beta_n)
186           
187        # for solvent
188        r0 = r[len(r)-1]           
189        r.append(r0)
190        beta.append(self.params['sld_solv'])
191        r_solv = 5*r0/4
192        r.append(r_solv)
193        beta.append(self.params['sld_solv'])
194       
195        return r, beta
196   
197    def setParam(self, name, value):
198        """
199        Set the value of a model parameter
200   
201        : param name: name of the parameter
202        : param value: value of the parameter
203        """
204        # set param to new model
205        self._setParamHelper( name, value)
206       
207        ## setParam to model
208        if name=='sld_solv':
209            # the sld_*** model.params not in params must set to value of sld_solv
210            for key in self.model.params.iterkeys():
211                if key not in self.params.keys()and key.split('_')[0] == 'sld':
212                        self.model.setParam(key, value)
213        self.model.setParam( name, value)
214       
215    def _setParamHelper(self, name, value):
216        """
217        Helper function to setParam
218        """
219        #look for dispersion parameters
220        toks = name.split('.')
221        if len(toks)==2:
222            for item in self.dispersion.keys():
223                if item.lower()==toks[0].lower():
224                    for par in self.dispersion[item]:
225                        if par.lower() == toks[1].lower():
226                            self.dispersion[item][par] = value
227                            return
228        # Look for standard parameter
229        for item in self.params.keys():
230            if item.lower()==name.lower():
231                self.params[item] = value
232                return
233       
234        raise ValueError, "Model does not contain parameter %s" % name
235             
236   
237    def _set_fixed_params(self):
238        """
239        Fill the self.fixed list with the model fixed list
240        """
241        for item in self.model.fixed:
242            if item.split('.')[0] in self.params.keys(): 
243                self.fixed.append(item)
244
245        self.fixed.sort()
246        pass         
247               
248    def run(self, x = 0.0):
249        """
250        Evaluate the model
251       
252        : param x: input q-value (float or [float, float] as [r, theta])
253        : return: (I value)
254        """
255
256        return self.model.run(x)
257
258    def runXY(self, x = 0.0):
259        """
260        Evaluate the model
261       
262        : param x: input q-value (float or [float, float] as [qx, qy])
263        : return: I value
264        """ 
265
266        return self.model.runXY(x)
267   
268    ## Now (May27,10) directly uses the model eval function
269    ## instead of the for-loop in Base Component.
270    def evalDistribution(self, x = []):
271        """
272        Evaluate the model in cartesian coordinates
273       
274        : param x: input q[], or [qx[], qy[]]
275        : return: scattering function P(q[])
276        """
277        # set effective radius and scaling factor before run
278        return self.model.evalDistribution(x)
279
280    def set_dispersion(self, parameter, dispersion):
281        """
282        Set the dispersion object for a model parameter
283       
284        : param parameter: name of the parameter [string]
285        :dispersion: dispersion object of type DispersionModel
286        """
287        value= None
288        try:
289            if parameter in self.model.dispersion.keys():
290                value= self.model.set_dispersion(parameter, dispersion)
291            self._set_dispersion()
292            return value
293        except:
294            raise 
Note: See TracBrowser for help on using the repository browser.