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

core_shell_microgelscostrafo411magnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 6431056 was 6431056, checked in by smk78, 7 years ago

Updated model docstrings for guinier_porod and unified_power_rg models
to explain relationship to one another, deficiency of unified_power_rg,
and add Hammouda references. (Relates to issue raised in email from
Jurrian, Jan 2017).

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