source: sasview/sansmodels/src/sans/models/CoreMultiShellModel.py @ 35aface

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 35aface was 35aface, checked in by Jae Cho <jhjcho@…>, 14 years ago

addede new models and attr. non_fittable

  • Property mode set to 100644
File size: 9.3 KB
Line 
1   
2from sans.models.BaseComponent import BaseComponent
3from sans.models.CoreFourShellModel import CoreFourShellModel
4import copy
5max_nshells = 4
6class CoreMultiShellModel(BaseComponent):
7    """
8    This multi-model is based on CoreFourShellModel and provides the capability
9    of changing the number of shells between 1 and 4.
10    """
11    def __init__(self, multfactor=1):
12        BaseComponent.__init__(self)
13        """
14        :param n_shells: number of shells in the model, assumes 1<= n_shells <=4.
15        """
16
17        ## Setting  model name model description
18        self.description=""
19        model = CoreFourShellModel()
20        self.model = model
21        self.name = "CoreMultiShellModel"
22        self.description=""
23        self.n_shells = multfactor
24        ## Define parameters
25        self.params = {}
26
27        ## Parameter details [units, min, max]
28        self.details = {}
29       
30        # non-fittable parameters
31        self.non_fittable = model.non_fittable
32       
33        ## dispersion
34        self._set_dispersion()
35        ## Define parameters
36        self._set_params()
37       
38        ## Parameter details [units, min, max]
39        self._set_details()
40       
41        #list of parameter that can be fitted
42        self._set_fixed_params() 
43       
44        ## functional multiplicity of the model
45        self.multiplicity = 5
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               
50       
51    def _clone(self, obj):
52        """
53        Internal utility function to copy the internal
54        data members to a fresh copy.
55        """
56        obj.params     = copy.deepcopy(self.params)
57        obj.description     = copy.deepcopy(self.description)
58        obj.details    = copy.deepcopy(self.details)
59        obj.dispersion = copy.deepcopy(self.dispersion)
60        obj.model  = self.model.clone()
61
62        return obj
63   
64   
65    def _set_dispersion(self):
66        """
67        model dispersions
68        Polydispersion should not be applied to s_model
69        """ 
70        ##set dispersion from model
71        for name , value in self.model.dispersion.iteritems():     
72            nshell = 0
73            if name.split('_')[0] == 'thick':
74                while nshell<self.n_shells:
75                    nshell += 1
76                    if name.split('_')[1] == 'shell%s' % str(nshell):
77                        self.dispersion[name]= value
78                    else: 
79                        continue
80            else:
81                self.dispersion[name]= value
82                             
83
84    def _set_params(self):
85        """
86        Concatenate the parameters of the model to create
87        this model parameters
88        """
89        # rearrange the parameters for the given # of shells
90        for name , value in self.model.params.iteritems():
91            nshell = 0
92            if name.split('_')[0] == 'thick' or name.split('_')[0] == 'sld':
93                if name.split('_')[1] == 'solv' or name.split('_')[1] == 'core':
94                    self.params[name]= value
95                    continue
96                while nshell<self.n_shells:
97                    nshell += 1
98                    if name.split('_')[1] == 'shell%s' % str(nshell):
99                        self.params[name]= value
100                        continue
101            else:
102                self.params[name]= value
103           
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
129                for nshell in range(self.n_shells,max_nshells):
130                    if key.split('_')[0] == 'sld' and key.split('_')[1] == 'shell%s' % str(nshell+1):
131                        try:
132                            value = self.model.params['sld_solv']
133                            self.model.setParam(key, value)
134                        except: pass
135
136    def getProfile(self):
137        """
138        Get SLD profile
139       
140        : return: (r, beta) where r is a list of radius of the transition points
141                beta is a list of the corresponding SLD values
142        : Note: This works only for func_shell# = 2.
143        """
144        r = []
145        beta = []
146        # for core at r=0
147        r.append(0)
148        beta.append(self.params['sld_core'])
149        # for core at r=rad_core
150        r.append(self.params['rad_core'])
151        beta.append(self.params['sld_core'])
152       
153        # for shells
154        for n in range(1,self.n_shells+1):
155            # Left side of each shells
156            r0 = r[len(r)-1]           
157            r.append(r0)
158            exec "beta.append(self.params['sld_shell%s'% str(n)])"
159
160            # Right side of each shells
161            exec "r0 += self.params['thick_shell%s'% str(n)]"
162            r.append(r0)
163            exec "beta.append(self.params['sld_shell%s'% str(n)])"
164           
165        # for solvent
166        r0 = r[len(r)-1]           
167        r.append(r0)
168        beta.append(self.params['sld_solv'])
169        r_solv = 5*r0/4
170        r.append(r_solv)
171        beta.append(self.params['sld_solv'])
172       
173        return r, beta
174
175    def setParam(self, name, value):
176        """
177        Set the value of a model parameter
178   
179        : param name: name of the parameter
180        : param value: value of the parameter
181        """
182        # set param to new model
183        self._setParamHelper( name, value)
184        ## setParam to model
185        if name=='sld_solv':
186            # the sld_*** model.params not in params must set to value of sld_solv
187            for key in self.model.params.iterkeys():
188                if key not in self.params.keys()and key.split('_')[0] == 'sld':
189                        self.model.setParam(key, value)
190        self.model.setParam( name, value)
191
192    def _setParamHelper(self, name, value):
193        """
194        Helper function to setParam
195        """
196        #look for dispersion parameters
197        toks = name.split('.')
198        if len(toks)==2:
199            for item in self.dispersion.keys():
200                if item.lower()==toks[0].lower():
201                    for par in self.dispersion[item]:
202                        if par.lower() == toks[1].lower():
203                            self.dispersion[item][par] = value
204                            return
205        # Look for standard parameter
206        for item in self.params.keys():
207            if item.lower()==name.lower():
208                self.params[item] = value
209                return
210       
211        raise ValueError, "Model does not contain parameter %s" % name
212             
213   
214    def _set_fixed_params(self):
215        """
216        Fill the self.fixed list with the model fixed list
217        """
218        for item in self.model.fixed:
219            if item.split('.')[0] in self.params.keys(): 
220                self.fixed.append(item)
221
222        self.fixed.sort()
223        pass         
224               
225    def run(self, x = 0.0):
226        """
227        Evaluate the model
228       
229        : param x: input q-value (float or [float, float] as [r, theta])
230        : return: (DAB value)
231        """
232        # set effective radius and scaling factor before run
233
234        return self.model.run(x)
235
236    def runXY(self, x = 0.0):
237        """
238        Evaluate the model
239       
240        : param x: input q-value (float or [float, float] as [qx, qy])
241        : return: DAB value
242        """ 
243        # set effective radius and scaling factor before run
244
245        return self.model.runXY(x)
246   
247    ## Now (May27,10) directly uses the model eval function
248    ## instead of the for-loop in Base Component.
249    def evalDistribution(self, x = []):
250        """
251        Evaluate the model in cartesian coordinates
252       
253        : param x: input q[], or [qx[], qy[]]
254        : return: scattering function P(q[])
255        """
256        # set effective radius and scaling factor before run
257        return self.model.evalDistribution(x)
258
259    def set_dispersion(self, parameter, dispersion):
260        """
261        Set the dispersion object for a model parameter
262       
263        : param parameter: name of the parameter [string]
264        :dispersion: dispersion object of type DispersionModel
265        """
266        value= None
267        try:
268            if parameter in self.model.dispersion.keys():
269                value= self.model.set_dispersion(parameter, dispersion)
270            self._set_dispersion()
271            return value
272        except:
273            raise 
Note: See TracBrowser for help on using the repository browser.