def test_oversampled_gridding():
    """
    Integration test of the convolve_to_grid function with oversampling

    Mostly tests same functionality as ``test_kernel_caching``.

    """
    # Let's grid a triangle function
    n_image = 8
    support = 2
    uv = np.array([(1.0, 0.0),
                   (1.3, 0.0),
                   (.01, -1.32),
                   ])

    vis = np.ones(len(uv), dtype=np.float_)
    vis_weights=np.ones_like(vis)
    kernel_func = conv_funcs.Triangle(2.0)

    vis_grid, sample_grid = convolve_to_grid(kernel_func,
                               support=support,
                               image_size=n_image,
                               uv=uv,
                               vis=vis,
                               vis_weights=vis_weights,
                               exact=False,
                               oversampling=9
                               )

    # simplification true since weights are all 1:
    assert vis_grid.sum() == vis.sum()
def test_triangle():
    # Now let's try a triangle function, larger support this time:
    n_image = 8
    support = 2
    uv = np.array([(1.0, 0.0)])
    subpix_offset = np.array([(0.1, -0.15)])
    vis = np.ones(len(uv), dtype=np.float_)

    # offset = np.array([(0.0, 0.0)])
    uv += subpix_offset
    kernel_func = conv_funcs.Triangle(2.0)

    grid, _ = convolve_to_grid(kernel_func,
                               support=support,
                               image_size=n_image,
                               uv=uv, vis=vis,
                               oversampling=None)

    kernel = Kernel(kernel_func=kernel_func, support=support,
                    offset=subpix_offset[0],
                    oversampling=1)
    assert grid.sum() == vis.sum()
    # uv location of sample is 1, therefore pixel index = n_image/2 +1
    xrange = slice(n_image / 2 + 1 - support, n_image / 2 + 1 + support + 1)
    yrange = slice(n_image / 2 - support, n_image / 2 + support + 1)
    assert (grid[yrange, xrange] == (kernel.array / kernel.array.sum())).all()
def test_triangle_func():
    triangle2 = conv_funcs.Triangle(half_base_width=2.0)

    io_pairs = np.array([
        [0.0, 1.0],
        [1.0, 0.5],
        [2.0, 0.0],
        [2.000001, 0.0],
        [100, 0.0],
        [0.1, 0.95],
        [0.5, 0.75],
    ])

    check_function_results_close(triangle2, io_pairs)
Пример #4
0
def test_stepped_vs_exact_convolution():
    # We use a triangle to compare, since even a tiny pixel offset should
    # result in differing values when using exact convolution,
    # this makes it easier to verify that the 'stepped' kernel is behaving
    # as expected.

    n_image = 8
    support = 3
    kernel_func = conv_funcs.Triangle(half_base_width=2.5)
    oversampling = 5

    # Choose sub-pixel steps that align with oversampling grid:
    steps = np.array([-0.4, 0.2, 0.0, 0.2, 0.4])
    substeps = np.linspace(-0.099999, 0.099999, num=50)

    kernel_cache = populate_kernel_cache(kernel_func=kernel_func,
                                         support=support,
                                         oversampling=oversampling)

    for x_offset in steps:
        offset = (x_offset, 0.0)
        aligned_exact_kernel = Kernel(kernel_func=kernel_func,
                                      support=support,
                                      offset=offset)
        aligned_cache_idx = calculate_oversampled_kernel_indices(
            offset, oversampling)
        cached_kernel = kernel_cache[tuple(aligned_cache_idx)]

        # Check that for oversampling-grid aligned positions, cache == exact
        assert (aligned_exact_kernel.array == cached_kernel.array).all()

        # Now check the results for non-aligned positions
        for sub_offset in substeps:
            offset = (x_offset + sub_offset, 0.0)
            if sub_offset != 0.0:
                unaligned_exact_kernel = Kernel(kernel_func=kernel_func,
                                                support=support,
                                                offset=offset)
                unaligned_cache_idx = calculate_oversampled_kernel_indices(
                    offset, oversampling)
                # We expect to return the same kernel as nearest grid-point
                assert (unaligned_cache_idx == aligned_cache_idx).all()
Пример #5
0
def make_image_map_fits(vis_path, output_dir, image_size, cell_size):
    out_path = derive_out_path(vis_path, output_dir, out_extension='.pyimg')

    uvw_in_wavelengths = casa_io.get_uvw_in_lambda(vis_path)
    stokes_i = casa_io.get_stokes_i_vis(vis_path)

    image_size = int(image_size.to(u.pix).value)
    grid_pixel_width_in_wavelengths = 1.0 / (cell_size.to(u.rad) * image_size)

    uvw_in_pixels = uvw_in_wavelengths / grid_pixel_width_in_wavelengths

    uv_in_pixels = uvw_in_pixels[:, :2]
    kernel = kfuncs.Triangle(1.5)
    uvgrid = exact_convolve_to_grid(kernel,
                                    support=2,
                                    image_size=image_size,
                                    uv=uv_in_pixels,
                                    vis=stokes_i)
    image = np.fft.ifftshift(np.fft.fft2(np.fft.fftshift(uvgrid)))
    return image
def test_regular_sampling_triangle():
    testfunc = conv_funcs.Triangle(half_base_width=1.5)
    support = 2
    oversampling = 1

    kernel_value_at_1pix = 1. - 1. / 1.5
    kv1 = kernel_value_at_1pix
    kv1sq = kv1 * kv1

    # Map subpixel offset to expected results
    expected_results = {}

    # No offset
    expected_results[(0., 0.)] = np.array([[0., 0., 0., 0., 0.],
                                           [0., kv1sq, kv1, kv1sq, 0.],
                                           [0., kv1, 1., kv1, 0.],
                                           [0., kv1sq, kv1, kv1sq, 0.],
                                           [0., 0., 0., 0., 0.]])

    # .5 pix offset right:
    kv_half = 1. - 0.5 / 1.5
    expected_results[(0.5, 0.)] = np.array(
        [[0., 0., 0., 0., 0.], [0., 0., kv_half * kv1, kv_half * kv1, 0.],
         [0., 0., kv_half, kv_half, 0.],
         [0., 0., kv_half * kv1, kv_half * kv1, 0.], [0., 0., 0., 0., 0.]])

    for offset, expected_array in expected_results.items():
        k = Kernel(
            kernel_func=testfunc,
            support=support,
            offset=offset,
            oversampling=oversampling,
            normalize=False,
        )

        assert (k.array == expected_array).all()
def test_kernel_caching():
    """
    Test generation of cached (offset) kernels, and demonstrate correct usage.

    In this test, we assume an oversampling of 5, resulting in
    step-widths of 0.2 regular pixels. We then iterate through a bunch of
    possible sub-pixel offsets, checking that we pick the nearest (closest to
    exact-positioned) cached kernel correctly.
    """
    # We use a triangle to compare, since even a tiny pixel offset should
    # result in differing values when using exact convolution,
    # this makes it easier to verify that the 'stepped' kernel is behaving
    # as expected.

    n_image = 8
    support = 3
    kernel_func = conv_funcs.Triangle(half_base_width=2.5)
    oversampling = 5

    # Choose sub-pixel steps that align with oversampling grid:
    steps = np.array([-0.4, 0.2, 0.0, 0.2, 0.4])
    substeps = np.linspace(-0.099999, 0.099999, num=15)

    kernel_cache = populate_kernel_cache(
        kernel_func=kernel_func, support=support, oversampling=oversampling)

    for x_offset in steps:
        offset = (x_offset, 0.0)
        aligned_exact_kernel = Kernel(kernel_func=kernel_func, support=support,
                                      offset=offset)
        # Generate an index into the kernel-cache at the precise offset
        # (i.e. a multiple of 0.2-regular-pixel-widths)
        aligned_cache_idx = calculate_oversampled_kernel_indices(offset,
                                                                 oversampling)
        cached_kernel = kernel_cache[tuple(aligned_cache_idx)]

        # Check that for oversampling-grid aligned positions, cache == exact
        assert (aligned_exact_kernel.array == cached_kernel.array).all()

        # Now check the results for non-aligned positions
        for sub_offset in substeps:
            offset = (x_offset + sub_offset, 0.0)
            if sub_offset != 0.0:
                unaligned_exact_kernel = Kernel(kernel_func=kernel_func,
                                                support=support, offset=offset)
                # Check that the irregular position resolves to the correct
                # nearby aligned position:
                unaligned_cache_idx = calculate_oversampled_kernel_indices(
                    offset, oversampling)
                assert (unaligned_cache_idx == aligned_cache_idx).all()

                ## Demonstrate retrieval of the cached kernel:
                cached_kernel = kernel_cache[tuple(unaligned_cache_idx)]
                assert (aligned_exact_kernel.array == cached_kernel.array).all()

                ## Sanity check - we expect the exact-calculated kernel to
                ## be different by a small amount
                diff = (
                    aligned_exact_kernel.array - unaligned_exact_kernel.array)
                eps = 10e-9
                assert not (np.fabs(diff) < eps).all()