1 | r""" |
---|
2 | This model calculates an empirical functional form for SAS data using SpericalSLD profile |
---|
3 | |
---|
4 | Similarly to the OnionExpShellModel, this model provides the form factor, P(q), for a multi-shell sphere, |
---|
5 | where the interface between the each neighboring shells can be described by one of a number of functions |
---|
6 | including error, power-law, and exponential functions. This model is to calculate the scattering intensity |
---|
7 | by building a continuous custom SLD profile against the radius of the particle. The SLD profile is composed |
---|
8 | of a flat core, a flat solvent, a number (up to 9 ) flat shells, and the interfacial layers between |
---|
9 | the adjacent flat shells (or core, and solvent) (see below). |
---|
10 | Unlike the OnionExpShellModel (using an analytical integration), |
---|
11 | the interfacial layers here are sub-divided and numerically integrated assuming each of the sub-layers are described |
---|
12 | by a line function. The number of the sub-layer can be given by users by setting the integer values of npts_inter |
---|
13 | in the GUI. The form factor is normalized by the total volume of the sphere. |
---|
14 | |
---|
15 | Definition |
---|
16 | ---------- |
---|
17 | |
---|
18 | The scattering intensity $I(q)$ in 1D is calculated as: |
---|
19 | |
---|
20 | .. math:: |
---|
21 | |
---|
22 | P(q) = \frac{f^2}{V_\text{particle}} |
---|
23 | f = f_\text{core} + \sum_{\text{inter}_i=0}^N f_text{inter}_i + |
---|
24 | \sum_{\text{flat}_i=0}^N f_text{flat}_i +f_\text{solvent} |
---|
25 | |
---|
26 | where, for a spherically symmetric particle with a particle density \rho(r) |
---|
27 | |
---|
28 | |
---|
29 | The scaling of the second power law region (coefficent C) is then automatically scaled to |
---|
30 | match the first by following formula |
---|
31 | |
---|
32 | .. math:: |
---|
33 | C = \frac{A}{qc^{-m1} qc^{-m2}} |
---|
34 | |
---|
35 | .. note:: |
---|
36 | Be sure to enter the power law exponents as positive values! |
---|
37 | |
---|
38 | For 2D data the scattering intensity is calculated in the same way as 1D, |
---|
39 | where the $q$ vector is defined as |
---|
40 | |
---|
41 | .. math:: |
---|
42 | |
---|
43 | q = \sqrt{q_x^2 + q_y^2} |
---|
44 | |
---|
45 | |
---|
46 | .. figure:: img/two_power_law_1d.jpg |
---|
47 | |
---|
48 | 1D plot using the default values (w/500 data point). |
---|
49 | |
---|
50 | References |
---|
51 | ---------- |
---|
52 | L A Feigin and D I Svergun, Structure Analysis by Small-Angle X-Ray and Neutron Scattering, Plenum Press, New York, (1987) |
---|
53 | |
---|
54 | """ |
---|
55 | |
---|
56 | from numpy import inf |
---|
57 | |
---|
58 | name = "spherical_sld" |
---|
59 | title = "Sperical SLD intensity calculation" |
---|
60 | description = """ |
---|
61 | I(q) = |
---|
62 | background = Incoherent background [1/cm] |
---|
63 | """ |
---|
64 | category = "shere-based" |
---|
65 | |
---|
66 | # pylint: disable=bad-whitespace, line-too-long |
---|
67 | # ["name", "units", default, [lower, upper], "type", "description"], |
---|
68 | parameters = [["n_shells", "", 1, [0, 9], "", "number of shells"], |
---|
69 | ["npts_inter", "", 35, [0, inf], "", "number of points in each sublayer"], |
---|
70 | ["sld_solv", "1/Ang^2", 1E-6,[-inf, inf], "","sld function solvent"], |
---|
71 | ["func_inter_0", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
72 | ["nu_inter_0", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
73 | ["thick_inter_0", "Ang", 50, [-inf, inf], "", "intern layer thickness"], |
---|
74 | ["sld_core_0", "1/Ang^2", 2.07E-6, [-inf, inf],"", "sld function flat"], |
---|
75 | ["rad_core_0", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
76 | ["func_inter_1", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
77 | ["nu_inter_1", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
78 | ["thick_inter_1", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
79 | ["sld_flat_1", "1/Ang^2", 4.06E-6, [-inf, inf],"", "sld function flat"], |
---|
80 | ["thick_flat_1", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
81 | ["func_inter_2", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
82 | ["nu_inter_2", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
83 | ["thick_inter_2", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
84 | ["sld_flat_2", "1/Ang^2", 3.56E-6, [-inf, inf],"", "sld function flat"], |
---|
85 | ["thick_flat_2", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
86 | ["func_inter_3", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
87 | ["nu_inter_3", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
88 | ["thick_inter_3", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
89 | ["sld_flat_3", "1/Ang^2", 4.06E-6, [-inf, inf],"", "sld function flat"], |
---|
90 | ["thick_flat_3", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
91 | ["func_inter_4", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
92 | ["nu_inter_4", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
93 | ["thick_inter_4", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
94 | ["sld_flat_4", "1/Ang^2", 3.5E-6, [-inf, inf],"", "sld function flat"], |
---|
95 | ["thick_flat_4", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
96 | ["func_inter_5", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
97 | ["nu_inter_5", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
98 | ["thick_inter_5", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
99 | ["sld_flat_5", "1/Ang^2", 4.06E-6, [-inf, inf],"", "sld function flat"], |
---|
100 | ["thick_flat_5", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
101 | ["func_inter_6", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
102 | ["nu_inter_6", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
103 | ["thick_inter_6", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
104 | ["sld_flat_6", "1/Ang^2", 3.5E-6, [-inf, inf],"", "sld function flat"], |
---|
105 | ["thick_flat_6", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
106 | ["func_inter_7", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
107 | ["nu_inter_7", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
108 | ["thick_inter_7", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
109 | ["sld_flat_7", "1/Ang^2", 4.06E-6, [-inf, inf],"", "sld function flat"], |
---|
110 | ["thick_flat_7", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
111 | ["func_inter_8", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
112 | ["nu_inter_8", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
113 | ["thick_inter_8", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
114 | ["sld_flat_8", "1/Ang^2", 3.5E-6, [-inf, inf],"", "sld function flat"], |
---|
115 | ["thick_flat_8", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
116 | ["func_inter_9", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
117 | ["nu_inter_9", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
118 | ["thick_inter_9", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
119 | ["sld_flat_9", "1/Ang^2", 4.06E-6, [-inf, inf],"", "sld function flat"], |
---|
120 | ["thick_flat_9", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
121 | ["func_inter_10", "", 3, [0, 4], "", "'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, 'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4"], |
---|
122 | ["nu_inter_10", "", 2.5, [-inf, inf], "", "steepness parameter"], |
---|
123 | ["thick_inter_10", "Ang", 50.0, [-inf, inf], "", "intern layer thickness"], |
---|
124 | ["sld_flat_10", "1/Ang^2", 3.5E-6, [-inf, inf],"", "sld function flat"], |
---|
125 | ["thick_flat_10", "Ang", 100.0, [-inf, inf], "", "flat layer_thickness"], |
---|
126 | ] |
---|
127 | # pylint: enable=bad-whitespace, line-too-long |
---|
128 | source = ["lib/librefl.c", "spherical_sld.c"] |
---|
129 | |
---|
130 | |
---|
131 | #TODO: Not clear if dispersion function is needed |
---|
132 | #def _set_dispersion(self): |
---|
133 | # """ |
---|
134 | # Setting dispersion for all shells |
---|
135 | # """ |
---|
136 | # ##set dispersion from model |
---|
137 | # for name , value in self.model.dispersion.iteritems(): |
---|
138 | # |
---|
139 | # nshell = -1 |
---|
140 | # if name.split('_')[0] == 'thick': |
---|
141 | # while nshell < 1: |
---|
142 | # nshell += 1 |
---|
143 | # if name.split('_')[1] == 'inter%s' % str(nshell): |
---|
144 | # self.dispersion[name] = value |
---|
145 | # else: |
---|
146 | # continue |
---|
147 | # else: |
---|
148 | # self.dispersion[name] = value |
---|
149 | |
---|
150 | |
---|
151 | def ER(radius): |
---|
152 | """ |
---|
153 | Calculate the effective radius for P(q)*S(q) |
---|
154 | Tale different radius values from corresponding shells |
---|
155 | |
---|
156 | :return: the value of the effective radius |
---|
157 | """ |
---|
158 | |
---|
159 | return radius |
---|
160 | |
---|
161 | |
---|
162 | demo = dict(scale=1, background=0.0, |
---|
163 | n_shells=1, |
---|
164 | sld_solv=1E-6, |
---|
165 | npts_inter=35, |
---|
166 | func_inter_0=3, |
---|
167 | nu_inter_0=2.5, |
---|
168 | rad_core_0=50.0, |
---|
169 | sld_core_0=2.07E-6, |
---|
170 | thick_inter_0=50, |
---|
171 | func_inter_1=3, |
---|
172 | nu_inter_1=2.5, |
---|
173 | thick_inter_1=50, |
---|
174 | sld_flat_1=4E-6, |
---|
175 | thick_flat_1=100, |
---|
176 | func_inter_2=3, |
---|
177 | nu_inter_2=2.5, |
---|
178 | thick_inter_2=50, |
---|
179 | sld_flat_2=3.5E-6, |
---|
180 | thick_flat_2=100, |
---|
181 | func_inter_3=3, |
---|
182 | nu_inter_3=2.5, |
---|
183 | thick_inter_3=50, |
---|
184 | sld_flat_3=4E-6, |
---|
185 | thick_flat_3=100, |
---|
186 | func_inter_4=3, |
---|
187 | nu_inter_4=2.5, |
---|
188 | thick_inter_4=50, |
---|
189 | sld_flat_4=3.5E-6, |
---|
190 | thick_flat_4=100, |
---|
191 | func_inter_5=3, |
---|
192 | nu_inter_5=2.5, |
---|
193 | thick_inter_5=50, |
---|
194 | sld_flat_5=3.5E-6, |
---|
195 | thick_flat_5=100, |
---|
196 | func_inter_6=3, |
---|
197 | nu_inter_6=2.5, |
---|
198 | thick_inter_6=50, |
---|
199 | sld_flat_6=3.5E-6, |
---|
200 | thick_flat_6=100, |
---|
201 | func_inter_7=3, |
---|
202 | nu_inter_7=2.5, |
---|
203 | thick_inter_7=50, |
---|
204 | sld_flat_7=4E-6, |
---|
205 | thick_flat_7=100, |
---|
206 | func_inter_8=3, |
---|
207 | nu_inter_8=2.5, |
---|
208 | thick_inter_8=50, |
---|
209 | sld_flat_8=3.5E-6, |
---|
210 | thick_flat_8=100, |
---|
211 | func_inter_9=3, |
---|
212 | nu_inter_9=2.5, |
---|
213 | thick_inter_9=50, |
---|
214 | sld_flat_9=4E-6, |
---|
215 | thick_flat_9=100, |
---|
216 | func_inter_10=3, |
---|
217 | nu_inter_10=2.5, |
---|
218 | thick_inter_10=50, |
---|
219 | sld_flat_10=3.5E-6, |
---|
220 | thick_flat_10=100 |
---|
221 | ) |
---|
222 | |
---|
223 | oldname = "SphericalSLDModel" |
---|
224 | oldpars = dict( |
---|
225 | scale="scale", |
---|
226 | background="background", |
---|
227 | rad_core_0 ="rad_core0", |
---|
228 | thick_inter_0 = "thick_inter0", |
---|
229 | nu_inter_0 = "nu_inter0", |
---|
230 | func_inter_0 = "func_inter0", |
---|
231 | thick_inter_1 = "thick_inter1", |
---|
232 | nu_inter_1 = "nu_inter1", |
---|
233 | func_inter_1 = "func_inter1") |
---|
234 | |
---|
235 | # n_shells="n_shells", |
---|
236 | # npts_inter='npts_inter', |
---|
237 | # sld_solv='sld_solv', |
---|
238 | # func_inter_0='func_inter0', |
---|
239 | # nu_inter_0='nu_inter0', |
---|
240 | # rad_core_0='rad_core0', |
---|
241 | # sld_core_0='sld_core0', |
---|
242 | # thick_inter_0='thick_inter0', |
---|
243 | # func_inter_1='func_inter1', |
---|
244 | # nu_inter_1='nu_inter1', |
---|
245 | # thick_inter_1='thick_inter1', |
---|
246 | # sld_flat_1='sld_flat1', |
---|
247 | # thick_flat_1='thick_flat1', |
---|
248 | # func_inter_2='func_inter2', |
---|
249 | # nu_inter_2='nu_inter2', |
---|
250 | # thick_inter_2='thick_inter2', |
---|
251 | # sld_flat_2='sld_flat2', |
---|
252 | # thick_flat_2='thick_flat2', |
---|
253 | # func_inter_3='func_inter3', |
---|
254 | # nu_inter_3='nu_inter3', |
---|
255 | # thick_inter_3='thick_inter3', |
---|
256 | # sld_flat_3='sld_flat3', |
---|
257 | # thick_flat_3='thick_flat3', |
---|
258 | # func_inter_4='func_inter4', |
---|
259 | # nu_inter_4='nu_inter4', |
---|
260 | # thick_inter_4='thick_inter4', |
---|
261 | # sld_flat_4='sld_flat4', |
---|
262 | # thick_flat_4='thick_flat4', |
---|
263 | # func_inter_5='func_inter5', |
---|
264 | # nu_inter_5='nu_inter5', |
---|
265 | # thick_inter_5='thick_inter5', |
---|
266 | # sld_flat_5='sld_flat5', |
---|
267 | # thick_flat_5='thick_flat5', |
---|
268 | # func_inter_6='func_inter6', |
---|
269 | # nu_inter_6='nu_inter6', |
---|
270 | # thick_inter_6='thick_inter6', |
---|
271 | # sld_flat_6='sld_flat6', |
---|
272 | # thick_flat_6='thick_flat6', |
---|
273 | # func_inter_7='func_inter7', |
---|
274 | # nu_inter_7='nu_inter7', |
---|
275 | # thick_inter_7='thick_inter7', |
---|
276 | # sld_flat_7='sld_flat7', |
---|
277 | # thick_flat_7='thick_flat7', |
---|
278 | # func_inter_8='func_inter8', |
---|
279 | # nu_inter_8='nu_inter8', |
---|
280 | # thick_inter_8='thick_inter8', |
---|
281 | # sld_flat_8='sld_flat8', |
---|
282 | # thick_flat_8='thick_flat8', |
---|
283 | # func_inter_9='func_inter9', |
---|
284 | # nu_inter_9='nu_inter9', |
---|
285 | # thick_inter_9='thick_inter9', |
---|
286 | # sld_flat_9='sld_flat9', |
---|
287 | # thick_flat_9='thick_flat9', |
---|
288 | # func_inter_10='func_inter10', |
---|
289 | # nu_inter_10='nu_inter10', |
---|
290 | # thick_inter_10='thick_inter10', |
---|
291 | # sld_flat_10='sld_flat10', |
---|
292 | # thick_flat_10='thick_flat10') |
---|
293 | |
---|
294 | tests = [ |
---|
295 | # Accuracy tests based on content in test/utest_extra_models.py |
---|
296 | [{'npts_iter':35, |
---|
297 | 'sld_solv':1E-6, |
---|
298 | 'func_inter_1':0.0, |
---|
299 | 'nu_inter':2.5, |
---|
300 | 'thick_inter_1':50, |
---|
301 | 'sld_flat_1':4E-6, |
---|
302 | 'thick_flat_1':100, |
---|
303 | 'func_inter_0':0.0, |
---|
304 | 'nu_inter_0':2.5, |
---|
305 | 'rad_core_0':50.0, |
---|
306 | 'sld_core_0':2.07E-6, |
---|
307 | 'thick_inter_0':50, |
---|
308 | 'background': 0.0, |
---|
309 | }, 0.001, 1000], |
---|
310 | ] |
---|