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

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since fa8e6dc was fa8e6dc, checked in by smk78, 5 years ago

Changed unified_power_Rg into unified_power_rg. Closes #1059

  • Property mode set to 100644
File size: 4.5 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) :ref:`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
62.. [#] B Hammouda, *A new Guinier-Porod model, J. Appl. Cryst.*, (2010), 43, 716-719
63.. [#] B Hammouda, *Analysis of the Beaucage model, J. Appl. Cryst.*, (2010), 43, 1474-1478
64
65Source
66------
67
68`guinier_porod.py <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/guinier_porod.py>`_
69
70Authorship and Verification
71----------------------------
72
73* **Author:**
74* **Last Modified by:**
75* **Last Reviewed by:**
76* **Source added by :** Steve King **Date:** March 25, 2019
77"""
78
79import numpy as np
80from numpy import inf, sqrt, exp, errstate
81
82name = "guinier_porod"
83title = "Guinier-Porod function"
84description = """\
85         I(q) = scale/q^s* exp ( - R_g^2 q^2 / (3-s) ) for q<= ql
86         = scale/q^porod_exp*exp((-ql^2*Rg^2)/(3-s))*ql^(porod_exp-s) for q>=ql
87                        where ql = sqrt((porod_exp-s)(3-s)/2)/Rg.
88                        List of parameters:
89                        scale = Guinier Scale
90                        s = Dimension Variable
91                        Rg = Radius of Gyration [A]
92                        porod_exp = Porod Exponent
93                        background  = Background [1/cm]"""
94
95category = "shape-independent"
96
97# pylint: disable=bad-whitespace, line-too-long
98#             ["name", "units", default, [lower, upper], "type","description"],
99parameters = [["rg", "Ang", 60.0, [0, inf], "", "Radius of gyration"],
100              ["s",  "",    1.0,  [0, inf], "", "Dimension variable"],
101              ["porod_exp",  "",    3.0,  [0, inf], "", "Porod exponent"]]
102# pylint: enable=bad-whitespace, line-too-long
103
104# pylint: disable=C0103
105def Iq(q, rg, s, porod_exp):
106    """
107    @param q: Input q-value
108    """
109    n = 3.0 - s
110    ms = 0.5*(porod_exp-s) # =(n-3+porod_exp)/2
111
112    # preallocate return value
113    iq = 0.0*q
114
115    # Take care of the singular points
116    if rg <= 0.0 or ms <= 0.0:
117        return iq
118
119    # Do the calculation and return the function value
120    idx = q < sqrt(n*ms)/rg
121    with errstate(divide='ignore'):
122        iq[idx] = q[idx]**-s * exp(-(q[idx]*rg)**2/n)
123        iq[~idx] = q[~idx]**-porod_exp * (exp(-ms) * (n*ms/rg**2)**ms)
124    return iq
125
126Iq.vectorized = True # Iq accepts an array of q values
127
128def random():
129    """Return a random parameter set for the model."""
130    rg = 10**np.random.uniform(1, 5)
131    s = np.random.uniform(0, 3)
132    porod_exp = s + np.random.uniform(0, 3)
133    pars = dict(
134        #scale=1, background=0,
135        rg=rg,
136        s=s,
137        porod_exp=porod_exp,
138    )
139    return pars
140
141demo = dict(scale=1.5, background=0.5, rg=60, s=1.0, porod_exp=3.0)
142
143tests = [[{'scale': 1.5, 'background':0.5}, 0.04, 5.290096890253155]]
Note: See TracBrowser for help on using the repository browser.