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

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 6550b64 was 318b5bbb, checked in by Jae Cho <jhjcho@…>, 12 years ago

Added polarization and magnetic stuffs

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