source: sasview/sansmodels/src/sans/models/FractalCoreShellModel.py @ 5650ebf

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

more models and some tests

  • Property mode set to 100644
File size: 8.4 KB
RevLine 
[8f20419d]1   
2from sans.models.BaseComponent import BaseComponent
3from sans.models.CoreShellModel import CoreShellModel
4from scipy.special import gammaln
5from math import exp, pow, sin, atan
6from copy import deepcopy
7
8class FractalCoreShellModel(BaseComponent):
9    """
10    Class that evaluates a FractalCoreShellModel
11    List of default parameters:
12    volfraction     = 0.05
13    radius          = 20.0 [A]
14    thickness       = 5.0 [A]
15    frac_dim        = 2.0
16    cor_length      = 100 [A]
17    core_sld        = 3.5e-006 [1/A^(2)]
18    shell_sld       = 1.0e-006 [1/A^(2)]
19    solvent_sld     = 6.35e-006 [1/A^(2)]
20    background      = 0.0 [1/cm]
21    """
22    def __init__(self):
23        BaseComponent.__init__(self)
24
25        ## Setting  model name model description
26        model = CoreShellModel()
27        self.description=model
28       
29        self.model = model
30        self.name = "FractalCoreShell"
31        self.description="""Scattering  from a fractal structure
32        with a primary building block of a spherical particle
33        with particle with a core-shell structure.
34        Note: Setting the (core) radius polydispersion with a Schulz
35        distribution is equivalent to the FractalPolyCore function
36        in NIST/Igor Package.
37        List of parameters:
38        volfraction: volume fraction of building block spheres
39        radius: radius of building block
40        thickness: shell thickness
41        frac_dim:  fractal dimension
42        cor_length: correlation length of fractal-like aggregates
43        core_sld: SLD of building block
44        shell_sld: SLD of shell
45        solvent_sld: SLD of matrix or solution
46        background: flat background"""
47       
48        ## Define parameters
49        self.params = {}
50
51        ## Parameter details [units, min, max]
52        self.details = {}
53       
54        # non-fittable parameters
55        self.non_fittable = model.non_fittable
56       
57        ## dispersion
58        self._set_dispersion()
59        ## Define parameters
60        self._set_params()
61       
62        ## Parameter details [units, min, max]
63        self._set_details()
64
65        ## parameters with orientation: can be removed since there is no orientational params
66        for item in self.model.orientation_params:
67            self.orientation_params.append(item)
68               
69    def _fractalcore(self,x):
70        """
71        Define model function
72       
73        return S(q): Fractal Structure
74        """
75        # set local variables
76        Df = self.params['frac_dim']
77        corr = self.params['cor_length']
78        r0 = self.params['radius']
79        #calculate S(q)
80        sq = Df*exp(gammaln(Df-1.0))*sin((Df-1.0)*atan(x*corr))
81        sq /= pow((x*r0),Df) * pow((1.0 + 1.0/(x*corr*x*corr)),((Df-1)/2))
82        sq += 1.0
83        return sq
84
85    def _clone(self, obj):
86        """
87        Internal utility function to copy the internal
88        data members to a fresh copy.
89        """
90        obj.params     = deepcopy(self.params)
91        obj.description     = deepcopy(self.description)
92        obj.details    = deepcopy(self.details)
93        obj.dispersion = deepcopy(self.dispersion)
94        obj.model  = self.model.clone()
95
96        return obj
97   
98    def _set_dispersion(self):
99        """
100        model dispersions
101        """ 
102        ##set dispersion from model
103        for name , value in self.model.dispersion.iteritems():     
104            self.dispersion[name]= value
105                             
106    def _set_params(self):
107        """
108        Concatenate the parameters of the model to create
109        this model parameters
110        """
111        # rearrange the parameters for the given # of shells
112        for name , value in self.model.params.iteritems():
113            if name == 'scale':
114                value = 0.05   
115            elif name == 'radius':
116                value = 20.0
117            elif name == 'thickness':
118                value = 5.0
119            elif name == 'core_sld':
120                value = 3.5e-06
121            elif name == 'shell_sld':
122                value = 1.0e-06
123            elif name == 'solvent_sld':
124                value = 6.35e-06
125            elif name == 'background':
126                value = 0.0
127            self.model.params[name]= value
128            if name  == 'scale':
129                name = 'volfraction'
130            self.params[name]= value
131        self.params['frac_dim'] = 2.0
132        self.params['cor_length'] = 100.0 
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():
141                if name == 'scale':
142                    name = 'volfraction'
143                self.details[name]= detail
144        self.details['frac_dim']   = ['', None, None]
145        self.details['cor_length'] = ['[A]', None, None] 
146
147
148    def setParam(self, name, value):
149        """
150        Set the value of a model parameter
151   
152        : param name: name of the parameter
153        : param value: value of the parameter
154        """
155        # set param to new model
156        self._setParamHelper(name, value)
157
158        if name == 'volfraction':
159            name = 'scale'
160        # model.setParam except the two names below
161        if name != 'frac_dim' and name != 'cor_length':
162            # background is always 0.0 in the coreshellmodel
163            if name == 'background':
164                value = 0.0
165            self.model.setParam(name, value)
166
167    def _setParamHelper(self, name, value):
168        """
169        Helper function to setParam
170        """
171        #look for dispersion parameters
172        toks = name.split('.')
173        if len(toks)==2:
174            for item in self.dispersion.keys():
175                if item.lower()==toks[0].lower():
176                    for par in self.dispersion[item]:
177                        if par.lower() == toks[1].lower():
178                            self.dispersion[item][par] = value
179                            return
180        # Look for standard parameter
181        for item in self.params.keys():
182            if item.lower()==name.lower():
183                self.params[item] = value
184                return
185       
186        raise ValueError, "Model does not contain parameter %s" % name
187             
188     
189               
190    def run(self, x = 0.0):
191        """
192        Evaluate the model
193       
194        : param x: input q-value (float or [float, float] as [r, theta])
195        : return: (DAB value)
196        """
197        if x.__class__.__name__ == 'list':
198            # Take absolute value of Q, since this model is really meant to
199            # be defined in 1D for a given length of Q
200            #qx = math.fabs(x[0]*math.cos(x[1]))
201            #qy = math.fabs(x[0]*math.sin(x[1]))
202            return self.params['background']+self._fractalcore(x[0])*self.model.run(x)
203        elif x.__class__.__name__ == 'tuple':
204            raise ValueError, "Tuples are not allowed as input to BaseComponent models"
205        else:
206            return self.params['background']+self._fractalcore(x)*self.model.run(x)
207
208
209        return self.params['background']+self._fractalcore(x)*self.model.run(x)
210
211    def runXY(self, x = 0.0):
212        """
213        Evaluate the model
214       
215        : param x: input q-value (float or [float, float] as [qx, qy])
216        : return: DAB value
217        """ 
218        if x.__class__.__name__ == 'list':
219            q = math.sqrt(x[0]**2 + x[1]**2)
220            return self.params['background']+self._fractalcore(q)*self.model.runXY(x)
221        elif x.__class__.__name__ == 'tuple':
222            raise ValueError, "Tuples are not allowed as input to BaseComponent models"
223        else:
224            return self.params['background']+self._fractalcore(x)*self.model.runXY(x)
225
226
227    def set_dispersion(self, parameter, dispersion):
228        """
229        Set the dispersion object for a model parameter
230       
231        : param parameter: name of the parameter [string]
232        :dispersion: dispersion object of type DispersionModel
233        """
234        value= None
235        try:
236            if parameter in self.model.dispersion.keys():
237                value= self.model.set_dispersion(parameter, dispersion)
238            self._set_dispersion()
239            return value
240        except:
241            raise 
Note: See TracBrowser for help on using the repository browser.