source: sasview/sansmodels/src/sans/models/CoreMultiShellModel.py @ 4c5448c

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 4c5448c was 339ce67, checked in by Jae Cho <jhjcho@…>, 14 years ago

added some models and tests

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