1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
r"""
Definition
----------
The scattering intensity $I(q)$ is calculated as
.. math::
I(q) = \begin{cases}
A q^{-m1} + \text{background} & q <= q_c \\
C q^{-m2} + \text{background} & q > q_c
\end{cases}
where $q_c$ = the location of the crossover from one slope to the other,
$A$ = the scaling coefficient that sets the overall intensity of the lower Q
power law region, $m1$ = power law exponent at low Q, and $m2$ = power law
exponent at high Q. The scaling of the second power law region (coefficient C)
is then automatically scaled to match the first by following formula:
.. math::
C = \frac{A q_c^{m2}}{q_c^{m1}}
.. note::
Be sure to enter the power law exponents as positive values!
For 2D data the scattering intensity is calculated in the same way as 1D,
where the $q$ vector is defined as
.. math::
q = \sqrt{q_x^2 + q_y^2}
References
----------
None.
Authorship and Verification
----------------------------
* **Author:** NIST IGOR/DANSE **Date:** pre 2010
* **Last Modified by:** Wojciech Wpotrzebowski **Date:** February 18, 2016
* **Last Reviewed by:** Paul Butler **Date:** March 21, 2016
"""
import numpy as np
from numpy import inf, power, empty, errstate
name = "two_power_law"
title = "This model calculates an empirical functional form for SAS data \
characterized by two power laws."
description = """
I(q) = coef_A*pow(qval,-1.0*power1) + background for q<=q_c
=C*pow(qval,-1.0*power2) + background for q>q_c
where C=coef_A*pow(q_c,-1.0*power1)/pow(q_c,-1.0*power2).
coef_A = scaling coefficient
q_c = crossover location [1/A]
power_1 (=m1) = power law exponent at low Q
power_2 (=m2) = power law exponent at high Q
background = Incoherent background [1/cm]
"""
category = "shape-independent"
# pylint: disable=bad-whitespace, line-too-long
# ["name", "units", default, [lower, upper], "type", "description"],
parameters = [
["coefficent_1", "", 1.0, [-inf, inf], "", "coefficent A in low Q region"],
["crossover", "1/Ang", 0.04,[0, inf], "", "crossover location"],
["power_1", "", 1.0, [0, inf], "", "power law exponent at low Q"],
["power_2", "", 4.0, [0, inf], "", "power law exponent at high Q"],
]
# pylint: enable=bad-whitespace, line-too-long
def Iq(q,
coefficent_1=1.0,
crossover=0.04,
power_1=1.0,
power_2=4.0,
):
"""
:param q: Input q-value (float or [float, float])
:param coefficent_1: Scaling coefficent at low Q
:param crossover: Crossover location
:param power_1: Exponent of power law function at low Q
:param power_2: Exponent of power law function at high Q
:return: Calculated intensity
"""
result = empty(q.shape, 'd')
index = (q <= crossover)
with errstate(divide='ignore'):
coefficent_2 = coefficent_1 * power(crossover, power_2 - power_1)
result[index] = coefficent_1 * power(q[index], -power_1)
result[~index] = coefficent_2 * power(q[~index], -power_2)
return result
Iq.vectorized = True # Iq accepts an array of q values
def random():
"""Return a random parameter set for the model."""
coefficient_1 = 1
crossover = 10**np.random.uniform(-3, -1)
power_1 = np.random.uniform(1, 6)
power_2 = np.random.uniform(1, 6)
pars = dict(
scale=1, #background=0,
coefficient_1=coefficient_1,
crossover=crossover,
power_1=power_1,
power_2=power_2,
)
return pars
tests = [
# Accuracy tests based on content in test/utest_extra_models.py
[{'coefficent_1': 1.0,
'crossover': 0.04,
'power_1': 1.0,
'power_2': 4.0,
'background': 0.0,
}, 0.001, 1000],
[{'coefficent_1': 1.0,
'crossover': 0.04,
'power_1': 1.0,
'power_2': 4.0,
'background': 0.0,
}, 0.150141, 0.125945],
[{'coefficent_1': 1.0,
'crossover': 0.04,
'power_1': 1.0,
'power_2': 4.0,
'background': 0.0,
}, 0.442528, 0.00166884],
[{'coefficent_1': 1.0,
'crossover': 0.04,
'power_1': 1.0,
'power_2': 4.0,
'background': 0.0,
}, (0.442528, 0.00166884), 0.00166884],
]
|