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

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

added sld plot for onion model and etc…

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