source: sasmodels/sasmodels/models/guinier_porod.py @ cc3fac6

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since cc3fac6 was cc3fac6, checked in by Doucet, Mathieu <doucetm@…>, 8 years ago

Convert Guinier-Porod model

  • Property mode set to 100644
File size: 4.2 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
41The cross-sectional radius-of-gyration for a randomly oriented cylinder
42of radius R is given by $R_g = R / \sqrt(2)$.
43
44The cross-sectional radius-of-gyration of a randomly oriented lamella
45of thickness $T$ is given by $R_g = T / \sqrt(12)$.
46
47For 2D data: The 2D scattering intensity is calculated in the same way as 1D,
48where the q vector is defined as
49
50.. math::
51    q = \sqrt{q_x^2+q_y^2}
52
53.. image:: img/guinier_porod_model.jpg
54
55    Figure 1: Guinier-Porod model for $R_g=100$ |Ang|, $s=1$, $m=3$, and $background=0.1$.
56
57
58Reference
59---------
60
61A Guinier, G Fournet, Small-Angle Scattering of X-Rays, John Wiley and Sons, New York, (1955)
62
63O Glatter, O Kratky, Small-Angle X-Ray Scattering, Academic Press (1982)
64Check out Chapter 4 on Data Treatment, pages 155-156.
65"""
66
67from numpy import inf, sqrt, power, exp
68
69name = "guinier_porod"
70title = "Guinier-Porod function"
71description = """\
72         I(q) = scale/q^s* exp ( - R_g^2 q^2 / (3-s) ) for q<= ql
73         = scale/q^m*exp((-ql^2*Rg^2)/(3-s))*ql^(m-s) for q>=ql
74                        where ql = sqrt((m-s)(3-s)/2)/Rg.
75                        List of parameters:
76                        scale = Guinier Scale
77                        s = Dimension Variable
78                        Rg = Radius of Gyration [A]
79                        m = Porod Exponent
80                        background  = Background [1/cm]"""
81
82category = "shape-independent"
83
84# pylint: disable=bad-whitespace, line-too-long
85#             ["name", "units", default, [lower, upper], "type","description"],
86parameters = [["rg", "Ang", 60.0, [0, inf], "", "Radius of gyration"],
87              ["s",  "",    1.0,  [0, inf], "", "Dimension variable"],
88              ["m",  "",    3.0,  [0, inf], "", "Porod exponent"]]
89# pylint: enable=bad-whitespace, line-too-long
90
91
92def Iq(q, rg, s, m):
93    """
94    @param q: Input q-value
95    """
96    n = 3.0 - s
97
98    # Take care of the singular points
99    if rg <= 0.0:
100        return 0.0
101    if (n-3.0+m) <= 0.0:
102        return 0.0
103
104    # Do the calculation and return the function value
105    q1 = sqrt((n-3.0+m)*n/2.0)/rg
106    if q < q1:
107        F = (1.0/power(q,(3.0-n)))*exp((-q*q*rg*rg)/n) 
108    else:
109        F = (1.0/power(q, m))*exp(-(n-3.0+m)/2.0)*power(((n-3.0+m)*n/2.0),
110                                    ((n-3.0+m)/2.0))/power(rg,(n-3.0+m))
111    return F
112
113Iq.vectorized = False  # Iq accepts an array of q values
114
115def Iqxy(qx, qy, *args):
116    """
117    @param qx:   Input q_x-value
118    @param qy:   Input q_y-value
119    @param args: Remaining arguments
120    """
121    return Iq(sqrt(qx ** 2 + qy ** 2), *args)
122
123Iqxy.vectorized = False # Iqxy accepts an array of qx, qy values
124
125demo = dict(scale=1.5, background=0.5, rg=60, s=1.0, m=3.0)
126
127oldname = "GuinierPorodModel"
128oldpars = dict(scale='scale', background='background', s='dim', m='m', rg='rg')
129
130tests = [[{'scale': 1.5, 'background':0.5}, 0.04, 5.290096890253155]]
Note: See TracBrowser for help on using the repository browser.