Math
- spinlab.math.lineshape.dysonian(x, x0, gamma, alpha, integral=1.0, deriv=False)
Dysonian distribution. Asymmetric lineshape from a mix of absorption (Lorentzian) and dispersion contributions, as observed by EPR/CESR on conducting samples where the microwave skin depth is comparable to or smaller than the sample size.
- Parameters:
x (array_like) -- input x
x0 (float) -- Center of distribution
gamma (float) -- Lorentzian width. 2*gamma is full width at half maximum (FWHM)
alpha (float) -- Asymmetry (dispersion-to-absorption mixing) parameter. alpha=0 reduces the Dysonian to a pure (symmetric) Lorentzian.
integral (float) -- Integral of the absorption (symmetric) part of the distribution
deriv (boolean) -- Derivative of a Dysonian distribution
- Returns:
Dysonian distribution
- Return type:
ndarray
The Dysonian distribution is defined as:
\[f(x) = \frac{1}{\pi} \left[\frac{\gamma + \alpha (x - x_0)}{(x-x_0)^2 + \gamma^2}\right]\]Derivative:
\[f(x) = \frac{1}{\pi} \left[\frac{\alpha \left(\gamma^2 - (x-x_0)^2\right) - 2 \gamma (x - x_0)}{\left( (x-x_0)^2 + \gamma^2 \right)^2}\right]\]Example
Evaluate a Dysonian at its center and its derivative off-center:
>>> from spinlab.math import lineshape >>> round(float(lineshape.dysonian(0, 0, gamma=1, alpha=0.5)), 4) 0.3183 >>> round(float(lineshape.dysonian(1, 0, gamma=1, alpha=0.5)), 4) 0.2387 >>> round(float(lineshape.dysonian(1, 0, gamma=1, alpha=0.5, deriv=True)), 4) -0.1592
- spinlab.math.lineshape.gaussian(x, x0, sigma, integral=1.0, deriv=False)
Gaussian distribution.
- Parameters:
x (array_like) -- input x
x0 (float) -- Center of distribution
sigma (float) -- Standard deviation of Gaussian distribution
integral (float) -- Integral of distribution
deriv (boolean) -- If True, return the first derivative of the Gaussian distribution instead of the distribution itself (e.g. for a field-modulated/phased spectrum). Defaults to False.
- Returns:
Gaussian distribution
- Return type:
ndarray
The Gaussian distribution is defined as:
\[f(x; x_0, \sigma) = \frac{1}{\sigma \sqrt{2 \pi}} \exp{\left(-\frac{(x-x_0)^2}{2 \sigma^2}\right)}\]Derivative:
\[f(x) = -\frac{x - x_0}{\sigma^3 \sqrt{2 \pi}} \exp{\left(-\frac{(x-x_0)^2}{2 \sigma^2}\right)}\]Example
Evaluate a Gaussian at its center and one standard deviation away, and its derivative one standard deviation away:
>>> from spinlab.math import lineshape >>> round(float(lineshape.gaussian(0, 0, sigma=1)), 4) 0.3989 >>> round(float(lineshape.gaussian(1, 0, sigma=1)), 4) 0.242 >>> round(float(lineshape.gaussian(1, 0, sigma=1, deriv=True)), 4) -0.242
- spinlab.math.lineshape.lorentzian(x, x0, gamma, integral=1.0, deriv=False)
Lorentzian Distribution.
- Parameters:
x (array_like) -- input x
x0 (float) -- Center of distribution
gamma (float) -- Lorentzian width. 2*gamma is full width at half maximum (FWHM)
integral (float) -- Integral of distribution
deriv (boolean) -- Derivative of a Lorentzian Distribution (Imaginary part of a phased spectrum)
- Returns:
Lorentzian distribution
- Return type:
ndarray
The Lorentzian distribution is defined as:
\[f(x) = \frac{1}{\pi \gamma} \left[\frac{\gamma^2}{(x-x_0)^2 + \gamma^2}\right]\]Derivative:
\[f(x) = \frac{1}{\pi \gamma} \left[\frac{- 2\gamma^2 (x-x_0)}{\left( (x-x_0)^2 + \gamma^2 \right)^2}\right]\]Example
Evaluate a Lorentzian at its center and its derivative off-center:
>>> from spinlab.math import lineshape >>> round(float(lineshape.lorentzian(0, 0, gamma=1)), 4) 0.3183 >>> round(float(lineshape.lorentzian(1, 0, gamma=1, deriv=True)), 4) -0.1592
- spinlab.math.lineshape.voigtian(x, x0, sigma, gamma, integral=1.0, deriv=False)
Voigtian distribution. Lineshape given by a convolution of Gaussian and Lorentzian distributions.
- Parameters:
x (array_like) -- input x
x0 (float) -- center of distribution
sigma (float) -- Gaussian Linewidth. Standard deviation of Gaussian distribution.
gamma (float) -- Lorentzian linewidth. 2*gamma is the full width at half maximum (FWHM)
integral (float) -- Integral of distribution
deriv (boolean) -- Derivative of a Voigtian distribution (Gaussian broadened imaginary part of a phased spectrum).
- Returns:
Voigtian distribution
- Return type:
ndarray
The Voigtian distribution is defined as:
\[f(x; x_0, \sigma, \gamma) = \frac{\operatorname{Re}[w(z)]}{\sigma \sqrt{2 \pi}}\]with
\[z = \frac{(x - x_0) + i\gamma}{\sigma \sqrt{2}}\]Derivative: .. math:
f(x) = \frac{1}{\sigma^3 \sqrt{2 \pi}} \left[ \gamma \operatorname{Im}[w(z)] - \left(x - x0\right) \operatorname{Re}[w(z)] \right]
with
\[z = \frac{\left( \left( x - x0 \right) + 1j \gamma \right)}{\sigma \sqrt{2}}\]Example
Evaluate a Voigtian at its center:
>>> from spinlab.math import lineshape >>> round(float(lineshape.voigtian(0, 0, sigma=1, gamma=1)), 4) 0.2087
- spinlab.math.relaxation.buildup_function(p, E_max, p_half)
Calculate an enhancement buildup curve with a baseline of 1.
- Parameters:
p (array_like) -- Microwave power values.
E_max (float) -- Saturating enhancement relative to the baseline.
p_half (float) -- Power where the enhancement term reaches half of
E_max.
- Returns:
Buildup curve evaluated at
p.- Return type:
ndarray
\[f(p) = 1 + E_\mathrm{max} \frac{p}{p_{1/2} + p}\]Examples
>>> import numpy as np >>> import spinlab as sl >>> power = np.array([0.0, 1.0, 2.0]) >>> y = sl.relaxation.buildup_function(power, E_max=-10.0, p_half=1.0)
- spinlab.math.relaxation.general_biexp(t, C1, C2, tau1, C3, tau2)
Calculate a bi-exponential curve.
- Parameters:
t (array_like) -- Time values.
C1 (float) -- Constant offset.
C2 (float) -- Amplitude of the first exponential component.
tau1 (float) -- Time constant of the first exponential component.
C3 (float) -- Amplitude of the second exponential component.
tau2 (float) -- Time constant of the second exponential component.
- Returns:
Bi-exponential curve evaluated at
t.- Return type:
ndarray
\[f(t) = C_1 + C_2 e^{-t/\tau_1} + C_3 e^{-t/\tau_2}\]Examples
>>> import numpy as np >>> import spinlab as sl >>> t = np.linspace(0.0, 5.0, 51) >>> y = sl.relaxation.general_biexp(t, C1=0.0, C2=1.0, tau1=0.5, C3=0.2, tau2=3.0)
- spinlab.math.relaxation.general_exp(t, C1, C2, tau)
Calculate a mono-exponential curve.
- Parameters:
t (array_like) -- Time values.
C1 (float) -- Constant offset.
C2 (float) -- Exponential amplitude.
tau (float) -- Exponential time constant.
- Returns:
Mono-exponential curve evaluated at
t.- Return type:
ndarray
\[f(t) = C_1 + C_2 e^{-t/\tau}\]Examples
>>> import numpy as np >>> import spinlab as sl >>> t = np.linspace(0.0, 5.0, 51) >>> y = sl.relaxation.general_exp(t, C1=0.0, C2=1.0, tau=2.0)
- spinlab.math.relaxation.ksigma_smax(p, E_max, p_half)
Calculate an asymptotic saturation curve without a baseline offset.
- Parameters:
p (array_like) -- Microwave power values.
E_max (float) -- Saturating value of the curve.
p_half (float) -- Power where the curve reaches half of
E_max.
- Returns:
Saturation curve evaluated at
p.- Return type:
ndarray
\[f(p) = E_\mathrm{max} \frac{p}{p_{1/2} + p}\]Examples
>>> import numpy as np >>> import spinlab as sl >>> power = np.array([0.0, 1.0, 2.0]) >>> y = sl.relaxation.ksigma_smax(power, E_max=5.0, p_half=1.0)
- spinlab.math.relaxation.logistic(x, c, x0, L, k)
Calculate a logistic growth curve.
- Parameters:
x (array_like) -- Input values.
c (float) -- Baseline offset.
x0 (float) -- Midpoint of the sigmoid.
L (float) -- Sigmoid amplitude.
k (float) -- Growth steepness.
- Returns:
Logistic curve evaluated at
x.- Return type:
ndarray
\[f(x) = c + \frac{L}{1 + e^{-k(x-x_0)}}\]Examples
>>> import numpy as np >>> import spinlab as sl >>> x = np.linspace(0.0, 1.0, 5) >>> y = sl.relaxation.logistic(x, c=0.0, x0=0.5, L=1.0, k=2.0)
- spinlab.math.relaxation.t1(t, T1, M_0, M_inf)
Calculate a T1 exponential recovery curve.
This form can describe inversion-recovery or saturation-recovery data depending on the chosen initial magnetization
M_0.- Parameters:
t (array_like) -- Time values.
T1 (float) -- Longitudinal relaxation time constant.
M_0 (float) -- Initial magnetization at
t = 0.M_inf (float) -- Equilibrium magnetization as
tapproaches infinity.
- Returns:
T1 recovery curve evaluated at
t.- Return type:
ndarray
\[f(t) = M_{\infty} - (M_{\infty} - M_0)e^{-t/T_1}\]Examples
>>> import numpy as np >>> import spinlab as sl >>> t = np.linspace(0.0, 10.0, 101) >>> y = sl.relaxation.t1(t, T1=2.0, M_0=-1.0, M_inf=1.0)
- spinlab.math.relaxation.t2(t, M_0, T2, p=1.0)
Calculate a stretched or mono-exponential T2 decay curve.
- Parameters:
t (array_like) -- Time values.
M_0 (float) -- Initial signal amplitude.
T2 (float) -- Transverse relaxation time constant.
p (float) -- Stretching exponent. The default
p=1gives a standard mono-exponential decay.
- Returns:
T2 decay curve evaluated at
t.- Return type:
ndarray
\[f(t) = M_0 e^{-(t/T_2)^p}\]Examples
>>> import numpy as np >>> import spinlab as sl >>> t = np.linspace(0.0, 5.0, 51) >>> y = sl.relaxation.t2(t, M_0=1.0, T2=1.5)
- spinlab.math.window.exponential(x, lw, shift=0.0)
Calculate exponential window function.
The window maximum is at
shift(default 0) and decays symmetrically on both sides. For data starting at 0 this reproduces the classic one-sided exponential decay.- Parameters:
x (array_like) -- Vector of points (e.g. time axis).
lw (int or float) -- Linewidth in Hz.
shift (float) -- Position of the window maximum (default: 0).
- Returns:
Exponential window function.
- Return type:
ndarray
\[\mathrm{exponential} = e^{-\pi \, |x - \mathrm{shift}| \, lw}\]
- spinlab.math.window.gaussian(x, lw, shift=0.0)
Calculate gaussian window function.
- Parameters:
x (array_like) -- Vector of points (e.g. time axis).
lw (float) -- Full width at half maximum (FWHM) of the Gaussian.
shift (float) -- Position of the window maximum (default: 0).
- Returns:
Gaussian window function.
- Return type:
ndarray
\[\begin{split}\sigma &= \frac{lw}{2\sqrt{2\ln(2)}} \\ \mathrm{gaussian} = e^{-2\pi^{2} \sigma^{2} (x - \mathrm{shift})^{2}}\end{split}\]
- spinlab.math.window.hamming(x, shift=0.0)
Calculate Hamming window function.
- Parameters:
x (array_like, int) -- Vector of points or number of points.
shift (float) -- Position of the window maximum (default: 0).
- Returns:
Hamming window function.
- Return type:
ndarray
\[\mathrm{hamming} = 0.53836 + 0.46164\cos\left(\pi \frac{x - \mathrm{shift}}{x_{\max}}\right)\]
- spinlab.math.window.hann(x, shift=0.0)
Calculate Hann window function.
- Parameters:
x (array_like, int) -- Vector of points or number of points.
shift (float) -- Position of the window maximum (default: 0).
- Returns:
Hann window function.
- Return type:
ndarray
\[\mathrm{hann} = 0.5 + 0.5\cos\left(\pi \frac{x - \mathrm{shift}}{x_{\max}}\right)\]
- spinlab.math.window.lorentz_gauss(x, lw, gauss_lw, gaussian_max=0)
Calculate lorentz-gauss window function.
- Parameters:
x (array_like) -- Vector of points.
lw (int or float) -- Exponential linewidth.
gauss_lw (int or float) -- Gaussian linewidth.
gaussian_max (int or float) -- Location of maximum in gaussian window.
- Returns:
Lorentz-Gauss window function.
- Return type:
ndarray
\[\begin{split}\mathrm{lorentz\_gauss} &= \exp(L - G^{2}) \\ L(t) &= \pi \cdot lw \cdot t \\ G(t) &= 0.6\pi \cdot gauss\_lw \cdot (\mathrm{gaussian\_max} \cdot (N - 1) - t)\end{split}\]
- spinlab.math.window.sin2(x, shift=0.0)
Calculate sin-squared window function.
- Parameters:
x (array_like, int) -- Vector of points or number of points.
shift (float) -- Position of the window maximum (default: 0).
- Returns:
Sin-squared window function.
- Return type:
ndarray
\[\sin^{2} = \cos\left(\frac{\pi}{2} \frac{x - \mathrm{shift}}{x_{\max}}\right)^{2}\]
- spinlab.math.window.traf(x, lw, shift=0.0)
Calculate TRAF (Trafficante) window function.
- Parameters:
x (array_like) -- Vector of points (e.g. time axis).
lw (float) -- Linewidth in Hz.
shift (float) -- Position of the window maximum (default: 0).
- Returns:
TRAF window function.
- Return type:
ndarray
\[\begin{split}\mathrm{traf} &= \frac{f_1 (f_1 + f_2)}{f_1^{2} + f_2^{2}} \\ f_1(t) &= \exp(-|t - \mathrm{shift}| \, \pi \, lw) \\ f_2(t) &= \exp(-(T_{\max} - |t - \mathrm{shift}|) \, \pi \, lw)\end{split}\]
The shaped pulses simulation
Author: Timothy Keller
Edit: Yen-Chun Huang
- spinlab.math.pulses.adiabatic(tp, BW, beta, resolution=1e-09)
Generate a complex hyperbolic-secant adiabatic pulse.
- Parameters:
tp (float) -- Pulse length.
BW (float) -- Pulse bandwidth.
beta (float) -- Dimensionless truncation factor.
resolution (float) -- Time resolution of the generated shape.
- Returns:
Tuple containing:
t (ndarray): Time axis. pulse (ndarray): Complex pulse shape.
- Return type:
tuple
\[\mathrm{pulse}(t) = \operatorname{sech}\left(\frac{\beta}{t_p} \left(t-\frac{t_p}{2}\right)\right)^{1+i\mu}\]with
\[\mu = \frac{\pi BW}{\beta/t_p}\]Examples
>>> import spinlab as sl >>> t, pulse = sl.pulses.adiabatic(tp=1e-6, BW=10e6, beta=5, resolution=1e-9)
- spinlab.math.pulses.chirp(tp, BW, resolution=1e-09)
Generate a complex quadratic chirp pulse.
- Parameters:
tp (float) -- Pulse length.
BW (float) -- Pulse bandwidth.
resolution (float) -- Time resolution of the generated shape.
- Returns:
Tuple containing:
t (ndarray): Time axis. pulse (ndarray): Complex pulse shape.
- Return type:
tuple
\[\mathrm{pulse}(t) = e^{i 2\pi \frac{k}{2}\left(t-\frac{t_p}{2}\right)^2}\]with
\[k = \frac{BW}{t_p}\]Examples
>>> import spinlab as sl >>> t, pulse = sl.pulses.chirp(tp=1e-6, BW=10e6, resolution=1e-9)
- spinlab.math.pulses.gaussian(tp, sigmas, resolution=1e-09)
Generate a Gaussian envelope pulse.
- Parameters:
tp (float) -- Pulse length.
sigmas (float) -- Number of standard deviations from the center to each pulse edge.
resolution (float) -- Time resolution of the generated shape.
- Returns:
Tuple containing:
t (ndarray): Time axis. pulse (ndarray): Complex-valued Gaussian envelope.
- Return type:
tuple
\[\mathrm{pulse}(t) = e^{-\frac{1}{2}\left(\frac{t-t_p/2}{\sigma}\right)^2}\]with
\[\sigma = \frac{t_p}{2\,\mathrm{sigmas}}\]Examples
>>> import spinlab as sl >>> t, pulse = sl.pulses.gaussian(tp=1e-6, sigmas=3, resolution=1e-9)
- spinlab.math.pulses.load_shape(filename)
Load a pulse shape from Xepr text shape format.
- Parameters:
filename (str or path-like) -- Path to a pulse shape file.
- Returns:
Complex-valued pulse shape. Real-only files are returned with zero imaginary components.
- Return type:
ndarray
Examples
>>> import spinlab as sl >>> pulse = sl.pulses.load_shape("shape.txt")
- spinlab.math.pulses.plane_wave(tp, f, resolution=1e-09)
Generate a complex plane-wave pulse.
- Parameters:
tp (float) -- Pulse length.
f (float) -- Plane-wave frequency.
resolution (float) -- Time resolution of the generated shape.
- Returns:
Tuple containing:
t (ndarray): Time axis. pulse (ndarray): Complex pulse shape.
- Return type:
tuple
\[\mathrm{pulse}(t) = e^{i2\pi f\left(t-\frac{t_p}{2}\right)}\]Examples
>>> import spinlab as sl >>> t, pulse = sl.pulses.plane_wave(tp=1e-6, f=1e6, resolution=1e-9)
- spinlab.math.pulses.save_shape(pulse_shape, filename, num=101)
Save a pulse shape in Xepr text shape format.
- Parameters:
pulse_shape (array_like) -- One-dimensional real or complex pulse shape.
filename (str or path-like) -- Output filename.
num (int) -- Xepr shape number written in the header and footer.
- Returns:
None
Examples
>>> import numpy as np >>> import spinlab as sl >>> pulse = np.array([0.0, 0.5, 1.0]) >>> sl.pulses.save_shape(pulse, "shape.txt", num=7)
- spinlab.math.pulses.sinc(tp, n, resolution=1e-09)
Generate a sinc pulse.
- Parameters:
tp (float) -- Pulse length.
n (float) -- Number of sinc lobes. Odd values produce a full symmetric sinc shape.
resolution (float) -- Time resolution of the generated shape.
- Returns:
Tuple containing:
t (ndarray): Time axis. pulse (ndarray): Sinc pulse shape.
- Return type:
tuple
\[\mathrm{pulse}(t) = \frac{\sin\left(\frac{\pi}{2}(n+1)x\right)}{x}\]with
\[x = \frac{t-t_p/2}{t_p/2}\]The center point uses the analytic limit
((n + 1) / 2) * piinstead of evaluating0 / 0.Examples
>>> import spinlab as sl >>> t, pulse = sl.pulses.sinc(tp=1e-6, n=3, resolution=1e-9)
- spinlab.math.pulses.square(tp, t_length=0.0, resolution=1e-09)
Generate a square pulse.
If
t_lengthis greater thantp, the pulse is centered in a longer zero-padded time axis. The active pulse interval is half-open:start <= t < stop.- Parameters:
tp (float) -- Pulse length.
t_length (float) -- Total length of the time axis. If this is less than or equal to
tp, the time axis length istp.resolution (float) -- Time resolution of the generated shape.
- Returns:
Tuple containing:
t (ndarray): Time axis. pulse (ndarray): Complex-valued square pulse.
- Return type:
tuple
Examples
>>> import spinlab as sl >>> t, pulse = sl.pulses.square(tp=1e-6, resolution=1e-9) >>> t, pulse = sl.pulses.square(tp=1e-6, t_length=2e-6, resolution=1e-9)
- spinlab.math.pulses.wurst(tp, N, resolution=1e-09)
Generate a WURST envelope pulse.
- Parameters:
tp (float) -- Pulse length.
N (float) -- WURST exponent controlling edge steepness.
resolution (float) -- Time resolution of the generated shape.
- Returns:
Tuple containing:
t (ndarray): Time axis. pulse (ndarray): Complex-valued WURST envelope.
- Return type:
tuple
\[\mathrm{pulse}(t) = 1 - \left|\cos\left(\frac{\pi}{t_p} \left(t-\frac{t_p}{2}\right)+\frac{\pi}{2}\right)\right|^N\]Examples
>>> import spinlab as sl >>> t, pulse = sl.pulses.wurst(tp=1e-6, N=20, resolution=1e-9)