Ejemplo n.º 1
0
def test_top_hat(radius: np.ndarray, a: float, order: int):
    f = generalised_top_hat(radius, a, order)
    kr, actual_ht = qdht(radius, f, order)
    v = kr / (2 * np.pi)
    expected_ht = generalised_jinc(v, a, order)
    error = np.mean(np.abs(expected_ht-actual_ht))
    assert error < 1e-3
Ejemplo n.º 2
0
def test_top_hat_equivalence(a: float, order: int, radius: np.ndarray):
    transformer = HankelTransform(order=order, radial_grid=radius)
    f = generalised_top_hat(radius, a, order)
    kr, one_shot_ht = qdht(radius, f, order=order)

    f_t = generalised_top_hat(transformer.r, a, transformer.order)
    standard_ht = transformer.qdht(f_t)
    assert np.allclose(one_shot_ht, standard_ht)
Ejemplo n.º 3
0
def test_gaussian(a: float, radius: np.ndarray):
    # Note the definition in Guizar-Sicairos varies by 2*pi in
    # both scaling of the argument (so use kr rather than v) and
    # scaling of the magnitude.
    f = np.exp(-a ** 2 * radius ** 2)
    kr, actual_ht = qdht(radius, f)
    expected_ht = 2*np.pi*(1 / (2 * a**2)) * np.exp(-kr**2 / (4 * a**2))
    assert np.allclose(expected_ht, actual_ht)
Ejemplo n.º 4
0
def test_gaussian_equivalence(a: float, radius: np.ndarray):
    # Note the definition in Guizar-Sicairos varies by 2*pi in
    # both scaling of the argument (so use kr rather than v) and
    # scaling of the magnitude.
    transformer = HankelTransform(order=0, radial_grid=radius)
    f = np.exp(-a ** 2 * radius ** 2)
    kr, one_shot_ht = qdht(radius, f)

    f_t = np.exp(-a ** 2 * transformer.r ** 2)
    standard_ht = transformer.qdht(f_t)
    assert np.allclose(one_shot_ht, standard_ht, rtol=1e-3, atol=1e-4)
Ejemplo n.º 5
0
def test_1_over_r2_plus_z2_equivalence(a: float):
    r = np.linspace(0, 50, 1024)
    f = 1 / (r ** 2 + a ** 2)
    transformer = HankelTransform(order=0, radial_grid=r)
    f_transformer = 1 / (transformer.r**2 + a**2)
    assert np.allclose(transformer.to_transform_r(f), f_transformer, rtol=1e-2, atol=1e-6)

    kr, one_shot_ht = qdht(r, f)
    assert np.allclose(kr, transformer.kr)
    standard_ht = transformer.qdht(f_transformer)
    assert np.allclose(one_shot_ht, standard_ht, rtol=1e-3, atol=1e-2)
Ejemplo n.º 6
0
def test_1_over_r2_plus_z2(a: float):
    # Note the definition in Guizar-Sicairos varies by 2*pi in
    # both scaling of the argument (so use kr rather than v) and
    # scaling of the magnitude.
    r = np.linspace(0, 50, 1024)
    f = 1 / (r**2 + a**2)
    # kn cannot handle complex arguments, so a must be real
    kr, actual_ht = qdht(r, f)
    expected_ht = 2 * np.pi * scipy_bessel.kn(0, a * kr)
    # as this diverges at zero, the first few entries have higher errors, so ignore them
    expected_ht = expected_ht[10:]
    actual_ht = actual_ht[10:]
    error = np.mean(np.abs(expected_ht - actual_ht))
    assert error < 1e-3
Ejemplo n.º 7
0
def test_gaussian_2d(axis: int, radius: np.ndarray):
    # Note the definition in Guizar-Sicairos varies by 2*pi in
    # both scaling of the argument (so use kr rather than v) and
    # scaling of the magnitude.
    a = np.linspace(2, 10)
    dims_a = np.ones(2, np.int)
    dims_a[1 - axis] = len(a)
    dims_r = np.ones(2, np.int)
    dims_r[axis] = len(radius)
    a_reshaped = np.reshape(a, dims_a)
    r_reshaped = np.reshape(radius, dims_r)
    f = np.exp(-a_reshaped**2 * r_reshaped**2)
    kr, actual_ht = qdht(radius, f, axis=axis)
    kr_reshaped = np.reshape(kr, dims_r)
    expected_ht = 2 * np.pi * (1 / (2 * a_reshaped**2)) * np.exp(
        -kr_reshaped**2 / (4 * a_reshaped**2))
    assert np.allclose(expected_ht, actual_ht)
Ejemplo n.º 8
0
def propagate_using_single_shot(r: np.ndarray,
                                field: np.ndarray) -> np.ndarray:
    kr, hankel_transform = qdht(r, field)

    propagated_field = np.zeros((nr, Nz), dtype=complex)
    kz = np.sqrt(k0**2 - kr**2)
    for n, z_loop in enumerate(z):
        phi_z = kz * z_loop  # Propagation phase
        hankel_transform_at_z = hankel_transform * np.exp(
            1j * phi_z)  # Apply propagation
        r_transform, field_at_z_transform_grid = iqdht(
            kr, hankel_transform_at_z)  # iQDHT
        f = interpolate.interp1d(r_transform,
                                 field_at_z_transform_grid,
                                 axis=0,
                                 fill_value='extrapolate',
                                 kind='cubic')
        propagated_field[:, n] = f(r)
    intensity = np.abs(propagated_field)**2
    return intensity
Ejemplo n.º 9
0
# %%
# First import the ``qdht`` function and other packages.
from pyhank import qdht
import numpy as np
import scipy.special
import matplotlib.pyplot as plt

# %%
# Create a grid for :math:`r` points and calculate the jinc function.
# The calculation fails at :math:`r = 0`, so we have to set that manually to the limit of :math:`1/2`.
r = np.linspace(0, 100, 1024)
f = np.zeros_like(r)
f[1:] = scipy.special.jv(1, r[1:]) / r[1:]
f[r == 0] = 0.5

plt.figure()
plt.plot(r, f)
plt.xlabel('Radius /m')

# %%
# Now take the Hankel transform using ``qdht``:
kr, ht = qdht(r, f)

plt.figure()
plt.plot(kr, ht)
plt.xlim([0, 5])
plt.xlabel('Radial wavevector /m$^{-1}$')

# %%
# As expected, this is a top-hat function bandlimited to :math:`k<1`, except for numerical error.
Ejemplo n.º 10
0
import matplotlib.pyplot as plt

from pyhank import qdht, iqdht, HankelTransform

# %%
# First we try a Gaussian function, the Hankel transform of which should also be Gaussian.
#
# Note the definition in Guizar-Sicairos [#Guizar]_ varies from that used by
# Pissens [#Pissens]_ by a factor of :math:`2\pi` in
# both scaling of the argument (so we use ``HankelTransform.kr`` rather than
# ``HankelTransform.v``) and also scaling of the magnitude.

a = 3
radius = np.linspace(0, 3, 1024)
f = np.exp(-a ** 2 * radius ** 2)
kr, actual_ht = qdht(radius, f)
expected_ht = 2*np.pi*(1 / (2 * a**2)) * np.exp(-kr**2 / (4 * a**2))
assert np.allclose(expected_ht, actual_ht)

plt.figure()
plt.subplot(2, 1, 1)
plt.title('Gaussian function')
plt.plot(radius, f)
plt.xlabel('Radius /$r$')
plt.subplot(2, 1, 2)
plt.plot(kr, expected_ht, label='Analytical')
plt.plot(kr, actual_ht, marker='x', linestyle='None', label='QDHT')
plt.title('Hankel transform - also Gaussian')
plt.xlabel('Frequency /$v$')
plt.xlim([0, 50])
plt.legend()