source: sasmodels/sasmodels/models/guinier_porod.py @ 46ed760

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

remove oldname/oldpars from new models

  • Property mode set to 100644
File size: 4.1 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, power, exp
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
96    # Take care of the singular points
97    if rg <= 0.0:
98        return 0.0
99    if (n-3.0+m) <= 0.0:
100        return 0.0
101
102    # Do the calculation and return the function value
103    q1 = sqrt((n-3.0+m)*n/2.0)/rg
104    if q < q1:
105        iq = (1.0/power(q, (3.0-n)))*exp((-q*q*rg*rg)/n)
106    else:
107        iq = (1.0/power(q, m))*exp(-(n-3.0+m)/2.0)*power(((n-3.0+m)*n/2.0),
108                                                         ((n-3.0+m)/2.0))/power(rg, (n-3.0+m))
109    return iq
110
111Iq.vectorized = False  # Iq accepts an array of q values
112
113def Iqxy(qx, qy, *args):
114    """
115    @param qx:   Input q_x-value
116    @param qy:   Input q_y-value
117    @param args: Remaining arguments
118    """
119    return Iq(sqrt(qx ** 2 + qy ** 2), *args)
120
121Iqxy.vectorized = False # Iqxy accepts an array of qx, qy values
122
123demo = dict(scale=1.5, background=0.5, rg=60, s=1.0, m=3.0)
124
125tests = [[{'scale': 1.5, 'background':0.5}, 0.04, 5.290096890253155]]
Note: See TracBrowser for help on using the repository browser.