Displaced core-shell ellipsoids - core_shell_displ_core.py

    r"""
Scattering model for displaced core-shell ellipsoids with polydispersity.

**Description**

This model calculates the scattering intensity from core-shell ellipsoids where
the core centre is displaced relative to the shell centre. The model accounts for:

- Size polydispersity (Gaussian distribution of particle radius, 50-point quadrature)
- Orientation averaging (50-point angular quadrature)
- Hard-sphere structure factor (Percus-Yevick closure)
- Debye (Gaussian chain) background contribution from free polymer

**Model Geometry**

The core is an ellipsoid with equatorial semi-axis *R* and aspect ratio *eps*
(semi-axes *R*, *R*, *R eps*).  The shell is a coaxial ellipsoid whose
equatorial outer radius is *R + d_shell*, where

.. math::

    d_\text{shell} = |d| + 2\,|\sigma_\text{out}|

with *d* = ``thickness_shell`` and :math:`\sigma_\text{out}` =
``sigma_outer``.  The core centre is offset by ``displacement`` in the
direction perpendicular to the symmetry axis.

**Mathematical Basis**

The scattering intensity returned by the kernel (before SASView applies the
global ``scale`` and ``background``) is:

.. math::

    I(q) = \bigl[ P(q) + \langle F(q)\rangle^2\,(S(q)-1) \bigr]\,B(q)
            + I_\text{poly}(q)

where

.. math::

    P(q) = \frac{\langle F^2(q)\rangle}{F_0^2}, \qquad
    B(q) = 1 + A_{10}\!\left(\frac{q_0}{q}\right)^{\!m},
    \qquad m = |A_{11}|+2, \quad q_0 = 0.001\,\text{Ang}^{-1}

- :math:`P(q)` — size- and orientation-averaged normalised form factor
- :math:`\langle F(q)\rangle/F_{\theta}` — mean reduced amplitude (used with S(q))
- :math:`S(q)` — Percus-Yevick hard-sphere structure factor
- :math:`B(q)` — empirical power-law low-*q* correction
- :math:`I_\text{poly}(q)` — Debye scattering from Gaussian polymer chains

The global intensity is then:

.. math::

    I_\text{total}(q) = \text{scale}\cdot I(q) + \text{background}

**Parameter Definitions**

``scale`` and ``background``
    Added automatically by SASView.  ``scale`` is an overall multiplicative
    factor (units of the desired absolute intensity scale).  ``background``
    is a flat incoherent baseline in cm\ :sup:`-1`.

``radius`` (*R*, Ang)
    Mean equatorial semi-axis of the core ellipsoid, i.e. the half-length
    along the two axes perpendicular to the symmetry axis.  This is the
    centre of the Gaussian size distribution.  Typical values: 5–200 Ang.

``aspect_ratio`` (*eps* = c/a, dimensionless)
    Ratio of the polar semi-axis to the equatorial semi-axis of the core.

    - eps = 1 -> sphere
    - eps > 1 -> prolate (cigar-shaped)
    - eps < 1 -> oblate (disc-shaped)

    The outer shell is constructed so that it has the same equatorial
    thickness *d_shell* everywhere: the shell's own aspect ratio is
    *(R·eps + d_shell) / (R + d_shell)*, which differs from eps unless
    d_shell = 0.

``volfraction_hs`` (*eta*, dimensionless)
    Volume fraction of particles used in the Percus-Yevick hard-sphere
    structure factor *S(q)*.  Set to 0 to suppress inter-particle
    interactions (i.e. *S(q)* = 1).  Physical upper limit for random
    close packing is ~ 0.64.

``radius_hs`` (*R*\ :sub:`HS`, Ang)
    Effective radius of the hard-sphere potential in the Percus-Yevick
    calculation.  This is the centre-to-centre distance at contact and
    need not equal the geometric particle radius; it is often larger to
    account for a hydration layer, electrostatic repulsion, or a polymer
    brush.  Only meaningful when ``volfraction_hs`` > 0.

``thickness_shell`` (*d*, Ang)
    Equatorial thickness of the shell layer.  The quantity actually used
    in the geometry is the effective shell extent

    .. math:: d_\text{shell} = |d| + 2\,|\sigma_\text{out}|

    so the outer radius of the ellipsoid is *R + d_shell*.  Note that
    ``sigma_outer`` also contributes to the shell extent (see below).

``contrast_shell`` (*A*\ :sub:`8`, dimensionless)
    Ratio of the shell SLD contrast to the core SLD contrast,
    :math:`\Delta\rho_\text{shell}/\Delta\rho_\text{core}`, where each
    :math:`\Delta\rho` is measured relative to the solvent.  The core
    form factor amplitude is weighted by (1 − contrast_shell):

    .. math::

        F(q) = V_\text{out}\,\phi(q\,r_\text{out})
               - V_\text{core}\,(1 - A_8)\,\phi(q\,r_\text{core})

    Limiting cases:

    - A\ :sub:`8` = 0 — the shell is invisible (delta rho\ :sub:`shell` = 0);
      the particle appears as a hollow ellipsoid.
    - A\ :sub:`8` = 1 — core and shell have equal contrast; the particle
      looks uniform (solid ellipsoid, no internal interface visible).
    - A\ :sub:`8` < 0 — shell and core scatter with opposite sign (e.g.
      a lipid membrane in D\ :sub:`2`\ O where the hydrocarbon core has
      negative contrast and the head-group shell has positive contrast).

``sigma_rel`` (*sigma*\ :sub:`R`/R, dimensionless)
    Relative standard deviation of the Gaussian size distribution of the
    core radius: :math:`\sigma_R = \sigma_\text{rel}\cdot R`.  The
    distribution is sampled symmetrically over 3 sigma\ :sub:`R` using 50
    Gauss points.  Example: ``sigma_rel`` = 0.05 means 5 percent polydispersity.
    Set to 0 for a monodisperse sample (the kernel uses a minimum width of
    10\ :sup:`-4`*R to avoid division by zero).

``power_law`` (*A*\ :sub:`10`, dimensionless)
    Amplitude of the empirical low-*q* power-law correction

    .. math:: B(q) = 1 + A_{10}\!\left(\frac{q_0}{q}\right)^{\!m}

    with *q*\ :sub:`0` = 0.001 Ang\ :sup:`-1` (fixed reference wavevector)
    and *m* = |``exponent_2``| + 2.  This term accounts for scattering
    from large-scale structures (e.g. fractal aggregates or density
    fluctuations) that dominate at very low *q*.  Set to 0 to disable.

``exponent_2`` (*A*\ :sub:`11`, dimensionless)
    Controls the exponent of the power-law correction through
    *m* = |A\ :sub:`11`| + 2.  The absolute value ensures *m* >= 2,
    which enforces a Porod-like decay at high *q* and prevents the
    correction from diverging.  Larger values of |A\ :sub:`11`| confine
    the correction to a narrower low-*q* range.

``sigma_outer`` (*sigma*\ :sub:`out`, Ang)
    Debye–Waller (Gaussian) roughness of the outer shell surface.  The
    outer form factor amplitude is multiplied by
    :math:`\exp(-\tfrac{1}{2}(q\,\sigma_\text{out})^2)`, smearing the
    outer interface.  *sigma*\ :sub:`out` also adds 2 sigma\ :sub:`out` to the
    effective shell thickness *d_shell*.  Set to 0 for a perfectly sharp
    outer surface.

``rg_polymer`` (*R*\ :sub:`g`, Ang)
    Radius of gyration of free Gaussian polymer chains in solution.
    Enters the Debye scattering function

    .. math::

        P_\text{Debye}(u) = \frac{2(\mathrm{e}^{-u}-1+u)}{u^2},
        \quad u = (q\,R_g)^2

    Only used when ``scale_polymer`` nonequal to 0.

``scale_polymer`` (*A*\ :sub:`14`, cm\ :sup:`-1`)
    Amplitude (zero-*q* intensity) of the Debye polymer contribution:
    :math:`I_\text{poly}(q) = A_{14}\,P_\text{Debye}(q)`.
    Set to 0 to disable.  Note that this term is *not* multiplied by the
    global ``scale``, so it represents an absolute polymer contribution
    independent of the particle scattering amplitude.

``displacement`` (*delta*, Ang)
    Distance by which the core centre is displaced from the shell centre,
    in the direction *perpendicular* to the ellipsoid symmetry axis.
    The displacement introduces an asymmetric contrast profile, generating
    a phase factor :math:`\cos(q\,\delta\,\sin\theta)` in the form factor
    (where *theta* is the angle between *q* and the symmetry axis).  This
    modulates the form factor oscillations and can model, for example, an
    off-centre protein domain inside a lipid vesicle.
    If *delta* exceeds *d_shell* the value is reflected back: effectively
    *delta* is clamped to [0, *d_shell*].  Set to 0 for a concentric
    core-shell particle.

``sigma_core`` (*sigma*\ :sub:`core`, Ang)
    Debye–Waller (Gaussian) roughness of the core–shell interface.  The
    core amplitude is multiplied by
    :math:`\exp(-\tfrac{1}{2}(q\,\sigma_\text{core})^2)`, smearing the
    inner interface.  Analogous to ``sigma_outer`` but applied at the
    inner surface.  Set to 0 for a sharp core–shell boundary.

**Notes on the Fortran Reference**

* The Fortran source had a bug in the amplitude accumulator: ``FFF =
  SUM1*STEP`` was used instead of ``SUM1X*STEP``, which caused the
  structure-factor correction term :math:`\langle F\rangle^2(S-1)` to
  vanish silently.  This has been corrected.
* The Fortran normalisation denominator used the angle-dependent ``RAO``
  (last integration point) instead of the angle-independent ``RO``; this
  has been corrected.

**References**

- Spinozzi et al., *Biophys. J.* (2002)
- Orthaber et al., *J. Appl. Cryst.* 33, 218–225 (2000)
"""

from numpy import inf

name  = "core_shell_displ_core"
title = "Displaced Core-Shell Ellipsoid with Polydispersity"
category = "shape:ellipsoid"
description = """
    Scattering from polydisperse core-shell ellipsoids with a displaced core.
    Includes a Percus-Yevick hard-sphere S(q) and a Debye polymer background.
"""

# Model parameters — 'scale' and 'background' are added automatically by SASView.
# Parameter order must match the Iq() argument order in the C kernel exactly.
parameters = [
    #   name               units   default    [lo,   hi]  type          description
    ["radius",         "Ang",    30.8,   [0,   inf], "volume",
     "Mean equatorial semi-axis of the core ellipsoid"],
    ["aspect_ratio",   "",        1.316,  [0,   inf], "volume",
     "Core polar/equatorial semi-axis ratio eps=c/a (>1 prolate, <1 oblate, =1 sphere)"],
    ["volfraction_hs", "",        0.0,    [0,  0.74], "",
     "Hard-sphere volume fraction eta for Percus-Yevick S(q); 0 = no interactions"],
    ["radius_hs",      "Ang",   100.0,   [0,   inf], "",
     "Hard-sphere interaction radius (centre-to-centre at contact); active only when volfraction_hs > 0"],
    ["thickness_shell","Ang",    11.19,  [0,   inf], "volume",
     "Equatorial shell thickness d; effective shell extent = d + 2*sigma_outer"],
    ["contrast_shell", "",       -0.304, [-inf, inf], "",
     "SLD contrast ratio Delta_rho_shell / Delta_rho_core; 0=hollow shell, 1=uniform particle"],
    ["sigma_rel",      "",        0.0205, [0,   inf], "",
     "Relative polydispersity sigma_R/R of the Gaussian size distribution; 0 = monodisperse"],
    ["power_law",      "",        8.70,  [-inf, inf], "",
     "Amplitude A10 of low-q power-law correction B(q)=1+A10*(0.001/q)^m; 0 = disabled"],
    ["exponent_2",     "",        0.0748,[-inf, inf], "",
     "Exponent parameter A11; actual power-law exponent m = |A11| + 2"],
    ["sigma_outer",    "Ang",     0.0,   [0,   inf], "",
     "Debye-Waller roughness sigma of the outer shell surface; 0 = sharp interface"],
    ["rg_polymer",     "Ang",    10.0,   [0,   inf], "",
     "Radius of gyration of free polymer chains (Debye scattering function)"],
    ["scale_polymer",  "",        0.01726,[-inf,inf], "",
     "Zero-q intensity of polymer Debye contribution I_poly(q); 0 = disabled"],
    ["displacement",   "Ang",     7.457, [-inf, inf], "",
     "Core-centre offset perpendicular to symmetry axis; 0 = concentric core-shell"],
    ["sigma_core",     "Ang",     0.0,   [0,   inf], "",
     "Debye-Waller roughness sigma of the core-shell interface; 0 = sharp interface"],
]

source = ["lib/sas_3j1x_x.c", "core_shell_displ_core.c"]

effective_radius_type = [
    "outer equatorial radius",
    "core equatorial radius",
]


def form_volume(radius, aspect_ratio, thickness_shell):
    import numpy as np
    r_outer   = radius + thickness_shell
    eps_outer = (radius*aspect_ratio + thickness_shell) / r_outer
    return 4.0*np.pi/3.0 * r_outer**3 * eps_outer


def radius_effective(mode, radius, aspect_ratio, thickness_shell):
    if mode == 1:
        return radius + thickness_shell
    else:
        return radius


def random():
    import numpy as np
    radius         = 10**np.random.uniform(1, 3)
    aspect_ratio   = np.random.uniform(0.5, 2.0)
    thickness_shell= np.random.uniform(0.05, 0.5)*radius
    volfraction_hs = np.random.uniform(0, 0.35)
    radius_hs      = np.random.uniform(0.8, 2.0)*radius
    contrast_shell = np.random.uniform(-1, 1)
    sigma_rel      = 10**np.random.uniform(-2, -0.3)
    power_law      = np.random.uniform(0, 15)
    exponent_2     = np.random.uniform(0, 1)
    sigma_outer    = np.random.uniform(0, 2)
    rg_polymer     = 10**np.random.uniform(0, 2)
    scale_polymer  = 10**np.random.uniform(-4, -1)
    displacement   = np.random.uniform(0, 0.8*thickness_shell)
    sigma_core     = np.random.uniform(0, 2)
    return dict(
        radius=radius, aspect_ratio=aspect_ratio,
        volfraction_hs=volfraction_hs, radius_hs=radius_hs,
        thickness_shell=thickness_shell, contrast_shell=contrast_shell,
        sigma_rel=sigma_rel, power_law=power_law, exponent_2=exponent_2,
        sigma_outer=sigma_outer, rg_polymer=rg_polymer,
        scale_polymer=scale_polymer, displacement=displacement,
        sigma_core=sigma_core,
    )


# Reference values computed from the Python reimplementation of Iq()
# with scale=1, background=0 (SASView adds background separately).
# Default parameters: radius=30.8, aspect_ratio=1.316, volfraction_hs=0,
#   radius_hs=100, thickness_shell=11.19, contrast_shell=-0.304,
#   sigma_rel=0.0205, power_law=8.70, exponent_2=0.0748, sigma_outer=0,
#   rg_polymer=10, scale_polymer=0.01726, displacement=7.457, sigma_core=0.
_default = {
    'scale': 1.0, 'background': 0.0,
    'radius': 30.8, 'aspect_ratio': 1.316,
    'volfraction_hs': 0.0, 'radius_hs': 100.0,
    'thickness_shell': 11.19, 'contrast_shell': -0.304,
    'sigma_rel': 0.0205, 'power_law': 8.70, 'exponent_2': 0.0748,
    'sigma_outer': 0.0, 'rg_polymer': 10.0, 'scale_polymer': 0.01726,
    'displacement': 7.457, 'sigma_core': 0.0,
}

tests = [
    # [parameters, q, expected_I]
    [_default, 0.01,  1.029576e+00],
    [_default, 0.05,  2.025142e-01],
    [_default, 0.10,  9.031598e-02],
    [_default, 0.20,  2.221160e-02],
    # With hard-sphere structure factor
    [dict(_default, volfraction_hs=0.2, radius_hs=50.0), 0.05, 2.037908e-01],
    [dict(_default, volfraction_hs=0.2, radius_hs=50.0), 0.10, 8.549888e-02],
]

Back to Model Download