예제 #1
0
    def test_pad_image(self):
        m31image = create_test_image(cellsize=0.001, frequency=[1e8], canonical=True)
        padded = pad_image(m31image, [1, 1, 1024, 1024])
        assert padded.shape == (1, 1, 1024, 1024)

        padded = pad_image(m31image, [3, 4, 2048, 2048])
        assert padded.shape == (3, 4, 2048, 2048)

        with self.assertRaises(ValueError):
            padded = pad_image(m31image, [1, 1, 100, 100])

        with self.assertRaises(IndexError):
            padded = pad_image(m31image, [1, 1])
예제 #2
0
 def test_fftim_factors(self):
     for i in [3, 5, 7]:
         npixel = 256 * i
         m31image = create_test_image(cellsize=0.001, frequency=[1e8], canonical=True)
         padded = pad_image(m31image, [1, 1, npixel, npixel])
         assert padded.shape == (1, 1, npixel, npixel)
         padded_fft = fft_image(padded)
         padded_fft_ifft = fft_image(padded_fft, m31image)
         numpy.testing.assert_array_almost_equal(padded.data, padded_fft_ifft.data.real, 12)
         padded_fft.data = numpy.abs(padded_fft.data)
         export_image_to_fits(padded_fft, fitsfile='%s/test_m31_fft_%d.fits' % (self.dir, npixel))
예제 #3
0
def get_kernel_list(vis: Visibility, im: Image, **kwargs):
    """Get the list of kernels, one per visibility
    
    """
    
    shape = im.data.shape
    npixel = shape[3]
    cellsize = numpy.pi * im.wcs.wcs.cdelt[1] / 180.0
    
    kernelname = get_parameter(kwargs, "kernel", "2d")
    oversampling = get_parameter(kwargs, "oversampling", 8)
    padding = get_parameter(kwargs, "padding", 2)

    gcf, _ = anti_aliasing_calculate((padding * npixel, padding * npixel), oversampling)
    
    wabsmax = numpy.max(numpy.abs(vis.w))
    if kernelname == 'wprojection' and wabsmax > 0.0:
        
        # wprojection needs a lot of commentary!
        log.debug("get_kernel_list: Using wprojection kernel")
        
        # The field of view must be as padded! R_F is for reporting only so that
        # need not be padded.
        fov = cellsize * npixel * padding
        r_f = (cellsize * npixel / 2) ** 2 / abs(cellsize)
        log.debug("get_kernel_list: Fresnel number = %f" % (r_f))
        delA = get_parameter(kwargs, 'wloss', 0.02)
        
        advice = advise_wide_field(vis, delA)
        wstep = get_parameter(kwargs, "wstep", advice['w_sampling_primary_beam'])
        
        log.debug("get_kernel_list: Using w projection with wstep = %f" % (wstep))
        
        # Now calculate the maximum support for the w kernel
        kernelwidth = get_parameter(kwargs, "kernelwidth",
                                    (2 * int(round(numpy.sin(0.5 * fov) * npixel * wabsmax * cellsize))))
        kernelwidth = max(kernelwidth, 8)
        assert kernelwidth % 2 == 0
        log.debug("get_kernel_list: Maximum w kernel full width = %d pixels" % (kernelwidth))
        padded_shape=[im.shape[0], im.shape[1], im.shape[2] * padding, im.shape[3] * padding]

        remove_shift = get_parameter(kwargs, "remove_shift", True)
        padded_image = pad_image(im, padded_shape)
        kernel_list = w_kernel_list(vis, padded_image, oversampling=oversampling, wstep=wstep,
                                    kernelwidth=kernelwidth, remove_shift=remove_shift)
    else:
        kernelname = '2d'
        kernel_list = standard_kernel_list(vis, (padding * npixel, padding * npixel),
                                           oversampling=oversampling)
    
    return kernelname, gcf, kernel_list
예제 #4
0
def w_kernel_list(vis: Visibility,
                  im: Image,
                  oversampling=1,
                  wstep=50.0,
                  kernelwidth=16,
                  **kwargs):
    """ Calculate w convolution kernels
    
    Uses create_w_term_like to calculate the w screen. This is exactly as wstacking does.

    Returns (indices to the w kernel for each row, kernels)

    Each kernel has axes [centre_v, centre_u, offset_v, offset_u]. We currently use the same
    convolution function for all channels and polarisations. Changing that behaviour would
    require modest changes here and to the gridding/degridding routines.

    :param vis: visibility
    :param image: Template image (padding, if any, occurs before this)
    :param oversampling: Oversampling factor
    :param wstep: Step in w between cached functions
    :return: (indices to the w kernel for each row, kernels)
    """

    nchan, npol, ny, nx = im.shape
    gcf, _ = anti_aliasing_calculate((ny, nx))

    assert oversampling % 2 == 0 or oversampling == 1, "oversampling must be unity or even"
    assert kernelwidth % 2 == 0, "kernelwidth must be even"

    wmaxabs = numpy.max(numpy.abs(vis.w))
    log.debug(
        "w_kernel_list: Maximum absolute w = %.1f, step is %.1f wavelengths" %
        (wmaxabs, wstep))

    def digitise(w, wstep):
        return numpy.ceil((w + wmaxabs) / wstep).astype('int')

    # Find all the unique indices for which we need a kernel
    nwsteps = digitise(wmaxabs, wstep) + 1
    w_list = numpy.linspace(-wmaxabs, +wmaxabs, nwsteps)

    print('====', nwsteps, wstep, len(w_list))

    wtemplate = copy_image(im)

    wtemplate.data = numpy.zeros(wtemplate.shape, dtype=im.data.dtype)

    padded_shape = list(wtemplate.shape)
    padded_shape[3] *= oversampling
    padded_shape[2] *= oversampling

    # For all the unique indices, calculate the corresponding w kernel
    kernels = list()
    for w in w_list:
        # Make a w screen
        wscreen = create_w_term_like(wtemplate, w, vis.phasecentre, **kwargs)
        wscreen.data /= gcf
        assert numpy.max(numpy.abs(wscreen.data)) > 0.0, 'w screen is empty'
        wscreen_padded = pad_image(wscreen, padded_shape)

        wconv = fft_image(wscreen_padded)
        wconv.data *= float(oversampling)**2
        # For the moment, ignore the polarisation and channel axes
        kernels.append(
            convert_image_to_kernel(wconv, oversampling,
                                    kernelwidth).data[0, 0, ...])

    # Now make a lookup table from row number of vis to the kernel
    kernel_indices = digitise(vis.w, wstep)
    assert numpy.max(kernel_indices) < len(kernels), "wabsmax %f wstep %f" % (
        wmaxabs, wstep)
    assert numpy.min(kernel_indices) >= 0, "wabsmax %f wstep %f" % (wmaxabs,
                                                                    wstep)
    return kernel_indices, kernels