source: sasmodels/sasmodels/models/guinier_porod.py @ 2c74c11

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 2c74c11 was 2c74c11, checked in by Paul Kienzle <pkienzle@…>, 8 years ago

implicit Iqxy; fix divide by 0 for q=0

  • Property mode set to 100644
File size: 3.8 KB
Line 
1# pylint: disable=line-too-long
2r"""
3Calculates the scattering for a generalized Guinier/power law object.
4This is an empirical model that can be used to determine the size
5and dimensionality of scattering objects, including asymmetric objects
6such as rods or platelets, and shapes intermediate between spheres
7and rods or between rods and platelets.
8
9Definition
10----------
11
12The following functional form is used
13
14.. math::
15    I(q) = \frac{G}{Q^s} \ \exp{\left[ \frac{-Q^2R_g^2}{3-s} \right]} \textrm{ for } Q \leq Q_1
16    \\
17    I(q) = D / Q^m \textrm{ for } Q \geq Q_1
18
19This is based on the generalized Guinier law for such elongated objects
20(see the Glatter reference below). For 3D globular objects (such as spheres), $s = 0$
21and one recovers the standard Guinier formula.
22For 2D symmetry (such as for rods) $s = 1$,
23and for 1D symmetry (such as for lamellae or platelets) $s = 2$.
24A dimensionality parameter ($3-s$) is thus defined, and is 3 for spherical objects,
252 for rods, and 1 for plates.
26
27Enforcing the continuity of the Guinier and Porod functions and their derivatives yields
28
29.. math::
30    Q_1 = \frac{1}{R_g} \sqrt{(m-s)(3-s)/2}
31
32and
33
34.. math::
35    D = G \ \exp{ \left[ \frac{-Q_1^2 R_g^2}{3-s} \right]} \ Q_1^{m-s}
36      = \frac{G}{R_g^{m-s}} \ \exp{\left[  -\frac{m-s}{2} \right]} \left( \frac{(m-s)(3-s)}{2} \right)^{\frac{m-s}{2}}
37
38
39Note that the radius-of-gyration for a sphere of radius R is given by $R_g = R \sqrt(3/5)$.
40
41For a cylinder of radius $R$ and length $L$,    $R_g^2 = \frac{L^2}{12} + \frac{R^2}{2}$
42
43from which the cross-sectional radius-of-gyration for a randomly oriented thin
44cylinder is $R_g = R / \sqrt(2)$.
45
46and the cross-sectional radius-of-gyration of a randomly oriented lamella
47of thickness $T$ is given by $R_g = T / \sqrt(12)$.
48
49For 2D data: The 2D scattering intensity is calculated in the same way as 1D,
50where the q vector is defined as
51
52.. math::
53    q = \sqrt{q_x^2+q_y^2}
54
55
56Reference
57---------
58
59A Guinier, G Fournet, Small-Angle Scattering of X-Rays, John Wiley and Sons, New York, (1955)
60
61O Glatter, O Kratky, Small-Angle X-Ray Scattering, Academic Press (1982)
62Check out Chapter 4 on Data Treatment, pages 155-156.
63"""
64
65from numpy import inf, sqrt, exp, errstate
66
67name = "guinier_porod"
68title = "Guinier-Porod function"
69description = """\
70         I(q) = scale/q^s* exp ( - R_g^2 q^2 / (3-s) ) for q<= ql
71         = scale/q^m*exp((-ql^2*Rg^2)/(3-s))*ql^(m-s) for q>=ql
72                        where ql = sqrt((m-s)(3-s)/2)/Rg.
73                        List of parameters:
74                        scale = Guinier Scale
75                        s = Dimension Variable
76                        Rg = Radius of Gyration [A]
77                        m = Porod Exponent
78                        background  = Background [1/cm]"""
79
80category = "shape-independent"
81
82# pylint: disable=bad-whitespace, line-too-long
83#             ["name", "units", default, [lower, upper], "type","description"],
84parameters = [["rg", "Ang", 60.0, [0, inf], "", "Radius of gyration"],
85              ["s",  "",    1.0,  [0, inf], "", "Dimension variable"],
86              ["m",  "",    3.0,  [0, inf], "", "Porod exponent"]]
87# pylint: enable=bad-whitespace, line-too-long
88
89# pylint: disable=C0103
90def Iq(q, rg, s, m):
91    """
92    @param q: Input q-value
93    """
94    n = 3.0 - s
95    ms = 0.5*(m-s) # =(n-3+m)/2
96
97    # preallocate return value
98    iq = 0.0*q
99
100    # Take care of the singular points
101    if rg <= 0.0 or ms <= 0.0:
102        return iq
103
104    # Do the calculation and return the function value
105    idx = q < sqrt(n*ms)/rg
106    with errstate(divide='ignore'):
107        iq[idx] = q[idx]**-s * exp(-(q[idx]*rg)**2/n)
108        iq[~idx] = q[~idx]**-m * (exp(-ms) * (n*ms/rg**2)**ms)
109    return iq
110
111Iq.vectorized = True # Iq accepts an array of q values
112
113demo = dict(scale=1.5, background=0.5, rg=60, s=1.0, m=3.0)
114
115tests = [[{'scale': 1.5, 'background':0.5}, 0.04, 5.290096890253155]]
Note: See TracBrowser for help on using the repository browser.