source: sasmodels/sasmodels/models/core_shell_parallelepiped.py @ 96153e4

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 96153e4 was 96153e4, checked in by butler, 6 years ago

more corrections and normalizations

Addreses #896. Brings parallelepiped and core-shell parallelepiped more
into line with each other and corrects angle definitions refering to
orietnational distribution docs for details. Still need to sort out
with Paul Kienzle the proper order the angles are applied.

  • Property mode set to 100644
File size: 10.5 KB
RevLine 
[44bd2be]1r"""
[5810f00]2Definition
3----------
4
[44bd2be]5Calculates the form factor for a rectangular solid with a core-shell structure.
[96153e4]6The thickness and the scattering length density of the shell or "rim" can be
7different on each (pair) of faces. The three dimensions of the core of the
8parallelepiped (strictly here a cuboid) may be given in *any* size order as
9long as the particles are randomly oriented (i.e. take on all possible
10orientations see notes on 2D below). To avoid multiple fit solutions, e
11specially with Monte-Carlo fit methods, it may be advisable to restrict their
12ranges. There may be a number of closely similar "best fits", so some trial and
13error, or fixing of some dimensions at expected values, may help.
[cb0dc22]14
[500128b]15The form factor is normalized by the particle volume $V$ such that
[44bd2be]16
[500128b]17.. math::
18
[dbf1a60]19    I(q) = \frac{\text{scale}}{V} \langle P(q,\alpha,\beta) \rangle
[367886f]20    + \text{background}
[44bd2be]21
[500128b]22where $\langle \ldots \rangle$ is an average over all possible orientations
[dbf1a60]23of the rectangular solid, and the usual $\Delta \rho^2 \ V^2$ term cannot be
24pulled out of the form factor term due to the multiple slds in the model.
[44bd2be]25
[96153e4]26The core of the solid is defined by the dimensions $A$, $B$, $C$ here shown
27such that $A < B < C$.
[44bd2be]28
[5bc373b]29.. figure:: img/parallelepiped_geometry.jpg
30
[331870d]31   Core of the core shell parallelepiped with the corresponding definition
[5bc373b]32   of sides.
33
[44bd2be]34
[500128b]35There are rectangular "slabs" of thickness $t_A$ that add to the $A$ dimension
36(on the $BC$ faces). There are similar slabs on the $AC$ $(=t_B)$ and $AB$
[dbf1a60]37$(=t_C)$ faces. The projection in the $AB$ plane is
[44bd2be]38
[5bc373b]39.. figure:: img/core_shell_parallelepiped_projection.jpg
40
[331870d]41   AB cut through the core-shell parallelipiped showing the cross secion of
42   four of the six shell slabs. As can be seen, this model leaves **"gaps"**
[dbf1a60]43   at the corners of the solid.
[44bd2be]44
[dbf1a60]45
46The total volume of the solid is thus given as
[44bd2be]47
48.. math::
49
50    V = ABC + 2t_ABC + 2t_BAC + 2t_CAB
51
[5810f00]52The intensity calculated follows the :ref:`parallelepiped` model, with the
53core-shell intensity being calculated as the square of the sum of the
[dbf1a60]54amplitudes of the core and the slabs on the edges. The scattering amplitude is
55computed for a particular orientation of the core-shell parallelepiped with
56respect to the scattering vector and then averaged over all possible
57orientations, where $\alpha$ is the angle between the $z$ axis and the $C$ axis
58of the parallelepiped, and $\beta$ is the angle between the projection of the
59particle in the $xy$ detector plane and the $y$ axis.
[44bd2be]60
[5810f00]61.. math::
[4493288]62
[dbf1a60]63    P(q)=\frac {\int_{0}^{\pi/2}\int_{0}^{\pi/2}F^2(q,\alpha,\beta) \ sin\alpha
64    \ d\alpha \ d\beta} {\int_{0}^{\pi/2} \ sin\alpha \ d\alpha \ d\beta}
[367886f]65
66and
67
68.. math::
69
[dbf1a60]70    F(q,\alpha,\beta)
[4493288]71    &= (\rho_\text{core}-\rho_\text{solvent})
72       S(Q_A, A) S(Q_B, B) S(Q_C, C) \\
73    &+ (\rho_\text{A}-\rho_\text{solvent})
[5bc373b]74        \left[S(Q_A, A+2t_A) - S(Q_A, A)\right] S(Q_B, B) S(Q_C, C) \\
[4493288]75    &+ (\rho_\text{B}-\rho_\text{solvent})
76        S(Q_A, A) \left[S(Q_B, B+2t_B) - S(Q_B, B)\right] S(Q_C, C) \\
77    &+ (\rho_\text{C}-\rho_\text{solvent})
78        S(Q_A, A) S(Q_B, B) \left[S(Q_C, C+2t_C) - S(Q_C, C)\right]
[393facf]79
80with
[5810f00]81
[393facf]82.. math::
[5810f00]83
[331870d]84    S(Q_X, L) = L \frac{\sin (\tfrac{1}{2} Q_X L)}{\tfrac{1}{2} Q_X L}
[4493288]85
86and
87
88.. math::
[5810f00]89
[5bc373b]90    Q_A &= q \sin\alpha \sin\beta \\
91    Q_B &= q \sin\alpha \cos\beta \\
92    Q_C &= q \cos\alpha
[4493288]93
94
95where $\rho_\text{core}$, $\rho_\text{A}$, $\rho_\text{B}$ and $\rho_\text{C}$
[331870d]96are the scattering lengths of the parallelepiped core, and the rectangular
[4493288]97slabs of thickness $t_A$, $t_B$ and $t_C$, respectively. $\rho_\text{solvent}$
98is the scattering length of the solvent.
[44bd2be]99
[dbf1a60]100.. note::
101
102   the code actually implements two substitutions: $d(cos\alpha)$ is
103   substituted for -$sin\alpha \ d\alpha$ (note that in the
104   :ref:`parallelepiped` code this is explicitly implemented with
105   $\sigma = cos\alpha$), and $\beta$ is set to $\beta = u \pi/2$ so that
106   $du = \pi/2 \ d\beta$.  Thus both integrals go from 0 to 1 rather than 0
107   to $\pi/2$.
108
[44bd2be]109FITTING NOTES
[4493288]110~~~~~~~~~~~~~
111
[44bd2be]112There are many parameters in this model. Hold as many fixed as possible with
113known values, or you will certainly end up at a solution that is unphysical.
114
115
116NB: The 2nd virial coefficient of the core_shell_parallelepiped is calculated
117based on the the averaged effective radius $(=\sqrt{(A+2t_A)(B+2t_B)/\pi})$
[4493288]118and length $(C+2t_C)$ values, after appropriately sorting the three dimensions
[331870d]119to give an oblate or prolate particle, to give an effective radius
[5bc373b]120for $S(q)$ when $P(q) * S(q)$ is applied.
[44bd2be]121
[904cd9c]122For 2d data the orientation of the particle is required, described using
[96153e4]123angles $\theta$, $\phi$ and $\Psi$ as in the diagrams below, for further details
124of the calculation and angular dispersions see :ref:`orientation` .
125
126The angle $\Psi$ is the rotational angle around the $C$ axis.
127For $\theta = 0$ and $\phi = 0$, $\Psi = 0$ corresponds to the $B$ axis
128oriented parallel to the y-axis of the detector with $A$ along the x-axis.
129For other $\theta$, $\phi$ values, the parallelepiped has to be first rotated
130$\theta$ degrees in the $z-x$ plane and then $\phi$ degrees around the $z$ axis,
131before doing a final rotation of $\Psi$ degrees around the resulting $C$ axis
132of the particle to obtain the final orientation of the parallelepiped.
[44bd2be]133
[dbf1a60]134.. note:: For 2d, constraints must be applied during fitting to ensure that the
135   inequality $A < B < C$ is not violated, and hence the correct definition
136   of angles is preserved. The calculation will not report an error,
137   but the results may be not correct.
[393facf]138
[15a90c1]139.. figure:: img/parallelepiped_angle_definition.png
[44bd2be]140
141    Definition of the angles for oriented core-shell parallelepipeds.
[2d81cfe]142    Note that rotation $\theta$, initially in the $xz$ plane, is carried
143    out first, then rotation $\phi$ about the $z$ axis, finally rotation
[331870d]144    $\Psi$ is now around the axis of the particle. The neutron or X-ray
[2d81cfe]145    beam is along the $z$ axis.
[44bd2be]146
[1916c52]147.. figure:: img/parallelepiped_angle_projection.png
[44bd2be]148
149    Examples of the angles for oriented core-shell parallelepipeds against the
150    detector plane.
151
[5bc6d21]152
153Validation
154----------
155
156Cross-checked against hollow rectangular prism and rectangular prism for equal
157thickness overlapping sides, and by Monte Carlo sampling of points within the
158shape for non-uniform, non-overlapping sides.
159
160
[aa2edb2]161References
162----------
[44bd2be]163
[5810f00]164.. [#] P Mittelbach and G Porod, *Acta Physica Austriaca*, 14 (1961) 185-211
165    Equations (1), (13-14). (in German)
166.. [#] D Singh (2009). *Small angle scattering studies of self assembly in
[fc0b7aa]167   lipid mixtures*, Johns Hopkins University Thesis (2009) 223-225. `Available
[5810f00]168   from Proquest <http://search.proquest.com/docview/304915826?accountid
169   =26379>`_
170
171Authorship and Verification
172----------------------------
[44bd2be]173
[5810f00]174* **Author:** NIST IGOR/DANSE **Date:** pre 2010
[331870d]175* **Converted to sasmodels by:** Miguel Gonzalez **Date:** February 26, 2016
[97be877]176* **Last Modified by:** Paul Kienzle **Date:** October 17, 2017
[44bd2be]177"""
178
179import numpy as np
[14207bb]180from numpy import pi, inf, sqrt, cos, sin
[44bd2be]181
182name = "core_shell_parallelepiped"
183title = "Rectangular solid with a core-shell structure."
184description = """
[8f04da4]185     P(q)=
[44bd2be]186"""
187category = "shape:parallelepiped"
188
189#             ["name", "units", default, [lower, upper], "type","description"],
[42356c8]190parameters = [["sld_core", "1e-6/Ang^2", 1, [-inf, inf], "sld",
[44bd2be]191               "Parallelepiped core scattering length density"],
[42356c8]192              ["sld_a", "1e-6/Ang^2", 2, [-inf, inf], "sld",
[44bd2be]193               "Parallelepiped A rim scattering length density"],
[42356c8]194              ["sld_b", "1e-6/Ang^2", 4, [-inf, inf], "sld",
[44bd2be]195               "Parallelepiped B rim scattering length density"],
[42356c8]196              ["sld_c", "1e-6/Ang^2", 2, [-inf, inf], "sld",
[44bd2be]197               "Parallelepiped C rim scattering length density"],
[42356c8]198              ["sld_solvent", "1e-6/Ang^2", 6, [-inf, inf], "sld",
[44bd2be]199               "Solvent scattering length density"],
[2222134]200              ["length_a", "Ang", 35, [0, inf], "volume",
[44bd2be]201               "Shorter side of the parallelepiped"],
[2222134]202              ["length_b", "Ang", 75, [0, inf], "volume",
[44bd2be]203               "Second side of the parallelepiped"],
[2222134]204              ["length_c", "Ang", 400, [0, inf], "volume",
[44bd2be]205               "Larger side of the parallelepiped"],
[2222134]206              ["thick_rim_a", "Ang", 10, [0, inf], "volume",
[44bd2be]207               "Thickness of A rim"],
[2222134]208              ["thick_rim_b", "Ang", 10, [0, inf], "volume",
[44bd2be]209               "Thickness of B rim"],
[2222134]210              ["thick_rim_c", "Ang", 10, [0, inf], "volume",
[44bd2be]211               "Thickness of C rim"],
[9b79f29]212              ["theta", "degrees", 0, [-360, 360], "orientation",
213               "c axis to beam angle"],
214              ["phi", "degrees", 0, [-360, 360], "orientation",
215               "rotation about beam"],
216              ["psi", "degrees", 0, [-360, 360], "orientation",
217               "rotation about c axis"],
[44bd2be]218             ]
219
[43b7eea]220source = ["lib/gauss76.c", "core_shell_parallelepiped.c"]
[44bd2be]221
222
[2222134]223def ER(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c):
[44bd2be]224    """
225        Return equivalent radius (ER)
226    """
[10ee838]227    from .parallelepiped import ER as ER_p
[44bd2be]228
[10ee838]229    a = length_a + 2*thick_rim_a
230    b = length_b + 2*thick_rim_b
231    c = length_c + 2*thick_rim_c
232    return ER_p(a, b, c)
[44bd2be]233
234# VR defaults to 1.0
235
[8f04da4]236def random():
237    outer = 10**np.random.uniform(1, 4.7, size=3)
238    thick = np.random.beta(0.5, 0.5, size=3)*(outer-2) + 1
239    length = outer - thick
240    pars = dict(
241        length_a=length[0],
242        length_b=length[1],
243        length_c=length[2],
244        thick_rim_a=thick[0],
245        thick_rim_b=thick[1],
246        thick_rim_c=thick[2],
247    )
248    return pars
249
[44bd2be]250# parameters for demo
251demo = dict(scale=1, background=0.0,
[14838a3]252            sld_core=1, sld_a=2, sld_b=4, sld_c=2, sld_solvent=6,
[2222134]253            length_a=35, length_b=75, length_c=400,
254            thick_rim_a=10, thick_rim_b=10, thick_rim_c=10,
[44bd2be]255            theta=0, phi=0, psi=0,
[2222134]256            length_a_pd=0.1, length_a_pd_n=1,
257            length_b_pd=0.1, length_b_pd_n=1,
258            length_c_pd=0.1, length_c_pd_n=1,
259            thick_rim_a_pd=0.1, thick_rim_a_pd_n=1,
260            thick_rim_b_pd=0.1, thick_rim_b_pd_n=1,
261            thick_rim_c_pd=0.1, thick_rim_c_pd_n=1,
[44bd2be]262            theta_pd=10, theta_pd_n=1,
263            phi_pd=10, phi_pd_n=1,
[14838a3]264            psi_pd=10, psi_pd_n=1)
[44bd2be]265
[4493288]266# rkh 7/4/17 add random unit test for 2d, note make all params different,
267# 2d values not tested against other codes or models
[fa70e04]268if 0:  # pak: model rewrite; need to update tests
269    qx, qy = 0.2 * cos(pi/6.), 0.2 * sin(pi/6.)
270    tests = [[{}, 0.2, 0.533149288477],
[2d81cfe]271             [{}, [0.2], [0.533149288477]],
272             [{'theta':10.0, 'phi':20.0}, (qx, qy), 0.0853299803222],
273             [{'theta':10.0, 'phi':20.0}, [(qx, qy)], [0.0853299803222]],
[fa70e04]274            ]
275    del qx, qy  # not necessary to delete, but cleaner
Note: See TracBrowser for help on using the repository browser.