Пример #1
0
def plot(method, strength=None):
    # test distribution
    source = SampleImage(n=2 * rmax - 1).image / scale
    Isrc, _ = Ibeta(source)
    Inorm = (Isrc**2).sum()

    # simulated projection fith Poissonian noise
    proj, _ = rbasex_transform(source, direction='forward')
    proj[proj < 0] = 0
    proj = np.random.RandomState(0).poisson(proj)  # (reproducible, see NEP 19)

    # reconstructed image and intensity
    if strength is None:
        reg = method
    else:
        reg = (method, strength)
    im, distr = rbasex_transform(proj, reg=reg)
    I, _ = distr.Ibeta()

    # plot...
    fig = plt.figure(figsize=(7, 3.5), frameon=False)

    # image
    plt.subplot(121)

    fig = plt.imshow(rescaleI(im), vmin=-vlim, vmax=vlim, cmap='bwr')

    plt.axis('off')
    plt.text(0, 2 * rmax, method, va='top')

    # intensity
    ax = plt.subplot2grid((3, 2), (0, 1), rowspan=2)

    ax.plot(Isrc, c='r', lw=1)
    ax.plot(I, c='k', lw=1)

    ax.set_xlim((0, rmax))
    ax.set_ylim(Ilim)

    # error
    plt.subplot(326)

    plt.axhline(c='r', lw=1)
    plt.plot(I - Isrc, c='b', lw=1)

    plt.xlim((0, rmax))
    plt.ylim(dIlim)

    # finish
    plt.subplots_adjust(left=0,
                        right=0.97,
                        wspace=0.1,
                        bottom=0.08,
                        top=0.98,
                        hspace=0.5)
Пример #2
0
def test_rbasex_zeros():
    rmax = 11
    n = 2 * rmax - 1
    im = np.zeros((n, n), dtype='float')

    fwd_im, fwd_distr = rbasex_transform(im, direction='forward')
    assert fwd_im.shape == (n, n)
    assert fwd_distr.r.shape == (rmax,)

    inv_im, inv_distr = rbasex_transform(im)
    assert inv_im.shape == (n, n)
    assert inv_distr.r.shape == (rmax,)
Пример #3
0
def rmse(method, strengths=None):
    if strengths is None:
        _, distr = rbasex_transform(proj, reg=method, out=None)
        I, _ = distr.Ibeta()
        return ((I - Isrc)**2).sum() / Inorm

    err = np.empty_like(strengths, dtype=float)
    for n, strength in enumerate(strengths):
        _, distr = rbasex_transform(proj, reg=(method, strength), out=None)
        I, _ = distr.Ibeta()
        err[n] = ((I - Isrc)**2).sum() / Inorm
    return err
Пример #4
0
def test_rbasex_gaussian():
    """Check an isotropic gaussian solution for rBasex"""
    rmax = 100
    sigma = 30
    n = 2 * rmax - 1

    ref = GaussianAnalytical(n, rmax, symmetric=True, sigma=sigma)
    # images as direct products
    src = ref.func * ref.func[:, None]
    proj = ref.abel * ref.func[:, None]  # (vertical is not Abel-transformed)

    fwd_im, fwd_distr = rbasex_transform(src, direction='forward')
    # whole image
    assert_allclose(fwd_im, proj, rtol=0.02, atol=0.001)
    # radial intensity profile (without r = 0)
    assert_allclose(fwd_distr.harmonics()[0, 1:], ref.abel[rmax:],
                    rtol=0.02, atol=5e-4)

    inv_im, inv_distr = rbasex_transform(proj)
    # whole image
    assert_allclose(inv_im, src, rtol=0.02, atol=0.02)
    # radial intensity profile (without r = 0)
    assert_allclose(inv_distr.harmonics()[0, 1:], ref.func[rmax:],
                    rtol=0.02, atol=1e-4)
Пример #5
0
def run_orders(odd=False):
    """
    Test angular orders using Gaussian peaks by comparison with hansenlaw.
    """
    maxorder = 6
    sigma = 5.0  # Gaussian sigma
    step = 6 * sigma  # distance between peak centers

    for order in range(maxorder + 1):
        rmax = int((order + 2) * step)
        if odd:
            if order == 0:
                continue  # 0th order cannot be odd
            height = 2 * rmax + 1
        else:  # even only
            if order % 2:
                continue  # skip odd
            height = rmax + 1
        # coordinates (Q0 or right half):
        x = np.arange(float(rmax + 1))
        y = rmax - np.arange(float(height))[:, None]
        # radius
        r = np.sqrt(x**2 + y**2)
        # cos, sin
        r[rmax, 0] = np.inf
        c = y / r
        s = x / r
        r[rmax, 0] = 0

        # Gaussian peak with one cossin angular term
        def peak(i):
            m = i  # cos power
            k = (order - m) & ~1  # sin power (round down to even)
            return c ** m * s ** k * \
                   np.exp(-(r - (i + 1) * step) ** 2 / (2 * sigma**2))

        # create source distribution
        src = peak(0)
        for i in range(1, order + 1):
            if not odd and i % 2:
                continue  # skip odd
            src += peak(i)

        # reference forward transform
        abel = hansenlaw_transform(src, direction='forward', hold_order=1)

        param = ', order = {}, odd = {}, '.format(order, odd)

        # test forward transform
        for mode in ['clean', 'cached']:
            if mode == 'clean':
                cache_cleanup()
            proj, _ = rbasex_transform(src, origin=(rmax, 0),
                                       order=order, odd=odd,
                                       direction='forward', out='fold')
            assert_allclose(proj, abel, rtol=0.003, atol=0.4,
                            err_msg='-> forward' + param + mode)

        # test inverse transforms
        for reg in [None, ('L2', 1), ('diff', 1), ('SVD', 1 / rmax)]:
            for mode in ['clean', 'cached']:
                if mode == 'clean':
                    cache_cleanup()
                recon, _ = rbasex_transform(abel, origin=(rmax, 0),
                                            order=order, odd=odd,
                                            reg=reg, out='fold')
                recon[rmax-2:rmax+3, :2] = 0  # exclude pixels near center
                assert_allclose(recon, src, atol=0.03,
                                err_msg='-> reg = ' + str(reg) + param + mode)
Пример #6
0
def run_out(odd=False):
    """
    Test some output shapes.
    """
    sigma = 5.0  # Gaussian sigma
    step = int(6 * sigma)  # distance between peak centers

    rmax = (2 + 2) * step
    size = 2 * rmax + 1
    # coordinates (full image):
    x = np.arange(float(size)) - rmax
    y = rmax - np.arange(float(size))[:, None]
    # radius
    r = np.sqrt(x**2 + y**2)
    # cos
    r[rmax, rmax] = np.inf
    c = y / r
    r[rmax, rmax] = 0

    # Gaussian peak with one cos^n angular term
    def peak(i):
        n = i if odd else 2 * i
        return c ** n * \
               np.exp(-(r - (i + 1) * step) ** 2 / (2 * sigma**2))

    # create source distribution
    src = peak(0) + peak(1)

    # reference forward transform
    abel = Transform(src, direction='forward', method='hansenlaw',
                     transform_options={'hold_order': 1}).transform

    param = '-> odd = {}, '.format(odd)

    # Test forward transform:

    # rmax < MIN => larger 'same'
    proj, _ = rbasex_transform(src, rmax=rmax - step, odd=odd,
                               direction='forward', out='same')
    assert_allclose(proj, abel, rtol=0.005, atol=0.2,
                    err_msg=param + 'rmax < MIN, out = same')

    # cropped, rmax = HOR < VER -> same
    crop = (slice(3 * step, -step // 2),
            slice(3 * step, -step))
    proj, _ = rbasex_transform(src[crop], origin=(step, step),
                               odd=odd, direction='forward', out='same')
    assert_allclose(proj, abel[crop], rtol=0.005, atol=0.2,
                    err_msg=param + 'rmax = HOR < VER, out = same')

    # cropped, rmax = VER < HOR -> same
    crop = (slice(step, -3 * step),
            slice(3 * step, -step // 2))
    proj, _ = rbasex_transform(src[crop], origin=(3 * step, step),
                               odd=odd, direction='forward', out='same')
    assert_allclose(proj, abel[crop], rtol=0.0003, atol=0.3,
                    err_msg=param + 'rmax = VER < HOR, out = same')

    # cropped, rmax = VER > HOR -> same
    crop = (slice(3 * step, -step // 2),
            slice(3 * step, -step))
    proj, _ = rbasex_transform(src[crop], origin=(step, step), rmax='MAX',
                               odd=odd, direction='forward', out='same')
    assert_allclose(proj, abel[crop], rtol=0.005, atol=0.2,
                    err_msg=param + 'rmax = VER > HOR, out = same')

    # cropped, rmax = HOR > VER -> same
    crop = (slice(step, -3 * step),
            slice(3 * step, -step // 2))
    proj, _ = rbasex_transform(src[crop], origin=(3 * step, step), rmax='MAX',
                               odd=odd, direction='forward', out='same')
    assert_allclose(proj, abel[crop], rtol=0.0003, atol=0.3,
                    err_msg=param + 'rmax = HOR > VER, out = same')

    # cropped, rmax = rmax -> full
    crop = (slice(3 * step, -step),
            slice(3 * step, -step))
    # (in multiples of step: VER^2 + HOR^2 = 2 * 3^2 > rmax^2 = 4^2)
    proj, _ = rbasex_transform(src[crop], origin=(step, step), rmax=rmax,
                               odd=odd, direction='forward', out='full')
    assert_allclose(proj, abel, rtol=0.002, atol=0.3,
                    err_msg=param + 'rmax = rmax, out = full')
Пример #7
0
def test_rbasex_pos():
    """
    Test positive regularization as in run_orders().
    """
    sigma = 5.0  # Gaussian sigma
    step = 6 * sigma  # distance between peak centers

    for order in [0, 1, 2, 4, 6]:
        rmax = int((order + 2) * step)
        if order == 1:  # odd
            rmax += int(step)  # 3 peaks instead of 2
            height = 2 * rmax + 1
        else:  # even only
            height = rmax + 1
        # coordinates (Q0 or right half):
        x = np.arange(float(rmax + 1))
        y = rmax - np.arange(float(height))[:, None]
        # radius
        r = np.sqrt(x**2 + y**2)
        # cos, sin
        r[rmax, 0] = np.inf
        c = y / r
        s = x / r
        r[rmax, 0] = 0

        # Gaussian peak with one cossin angular term
        def peak(i, isotropic=False):
            if isotropic:
                return np.exp(-(r - (i + 1) * step) ** 2 / (2 * sigma**2))
            m = i  # cos power
            k = (order - m) & ~1  # sin power (round down to even)
            return c ** m * s ** k * \
                   np.exp(-(r - (i + 1) * step) ** 2 / (2 * sigma**2))

        # create source distribution
        src = peak(0)
        if order == 1:  # special case
            src += (1 + c) * peak(1, True)  # 1 + cos >= 0
            src += (1 - c) * peak(2, True)  # 1 - cos >= 0
        else:  # other even orders
            for i in range(2, order + 1, 2):
                src += peak(i)
        # array for nonnegativity test (with some tolerance)
        zero = np.full_like(src, -1e-15)

        # reference forward transform
        abel = hansenlaw_transform(src, direction='forward', hold_order=1)
        # with some noise
        abel += 0.05 * np.random.RandomState(0).rand(*abel.shape)

        param = '-> order = {}, '.format(order)

        # test inverse transform
        for mode in ['clean', 'cached']:
            if mode == 'clean':
                cache_cleanup()
            recon, _ = rbasex_transform(abel, origin=(rmax, 0),
                                        order=order,
                                        reg='pos', out='fold')
            recon[rmax-3:rmax+4, :2] = 0  # exclude pixels near center
            assert_allclose(recon, src, atol=0.05,
                            err_msg=param + mode)
            # check nonnegativity
            assert_array_less(zero, recon)
Пример #8
0
import numpy as np
import matplotlib.pyplot as plt

from abel.tools.analytical import SampleImage
from abel.tools.vmi import Ibeta
from abel.rbasex import rbasex_transform

# test distribution
rmax = 200
scale = 10000
source = SampleImage(n=2 * rmax - 1).image / scale
Isrc, _ = Ibeta(source)
Inorm = (Isrc**2).sum()

# simulated projection fith Poissonian noise
proj, _ = rbasex_transform(source, direction='forward')
proj[proj < 0] = 0
proj = np.random.RandomState(0).poisson(proj)  # (reproducible, see NEP 19)


# calculate relative RMS error for given regularization parameters
def rmse(method, strengths=None):
    if strengths is None:
        _, distr = rbasex_transform(proj, reg=method, out=None)
        I, _ = distr.Ibeta()
        return ((I - Isrc)**2).sum() / Inorm

    err = np.empty_like(strengths, dtype=float)
    for n, strength in enumerate(strengths):
        _, distr = rbasex_transform(proj, reg=(method, strength), out=None)
        I, _ = distr.Ibeta()
dmask = 1 * (mask1 - binary_erosion(mask1, structure=brush)) + \
        2 * (mask2 - binary_erosion(mask2, structure=brush)) + \
        3 * (mask3 - binary_erosion(mask3, structure=brush))
dmask[dmask == 0] = np.nan
from matplotlib.colors import ListedColormap
rgb = ListedColormap(['#CC0000', '#00AA00', '#0055FF'])
plt.imshow(dmask, extent=(0, w, 0, h), cmap=rgb, interpolation='nearest')

# Analyze the left part and plot results
plt.subplot(222)
plt.title('Distributions: left image')
# the reconstructed image is not used in this example, so it is not created;
# also notice that order=0 is enough for this totally isotropic case
_, distr = rbasex_transform(im,
                            origin=origin1,
                            rmax=r1,
                            order=0,
                            weights=mask1,
                            out=None)
r, I = distr.rIbeta()
plt.plot(r, I, c=rgb(0), label='$I(r)$')
plt.legend()
plt.autoscale(enable=True, tight=True)

# Analyze the central part and plot results
plt.subplot(223)
plt.title('Distributions: central image')
# here the default order=2 is needed and used
_, distr = rbasex_transform(im,
                            origin=origin2,
                            rmax=r2,
                            weights=mask2,
Пример #10
0
R = 150  # image radius
N = 2 * R + 1  # full image width and height
block_r = 20  # beam-block disk radius
block_w = 5  # beam-block holder width

vlim = 3.6  # intensity limits for images
ylim = (-1.3, 2.7)  # limits for plots

# create source distribution and its profiles for reference
source = SampleImage(N).func / 100
r_src, P0_src, P2_src = rharmonics(source)

# simulate experimental image:
# projection
im, _ = rbasex_transform(source, direction='forward')
# Poissonian noise
im[im < 0] = 0
im = np.random.RandomState(0).poisson(im)
# image coordinates
im_x = np.arange(float(N)) - R
im_y = R - np.arange(float(N))[:, None]
im_r = np.sqrt(im_x**2 + im_y**2)
# simulate beam-block shadow
im = im / (1 + np.exp(-(im_r - block_r)))
im[:R] *= 1 / (1 + np.exp(-(np.abs(im_x) - block_w)))

# create mask that fully covers beam-block shadow
mask_r = block_r + 5
mask_w = block_w + 5
mask = np.ones_like(im)