Esempio n. 1
0
def invert_wstack_single(vis: Visibility, im: Image, dopsf, normalize=True, invert_inner=invert_2d_base, **kwargs) -> (Image, numpy.ndarray):
    """Process single w slice
    
    :param vis: Visibility to be inverted
    :param im: image template (not changed)
    :param dopsf: Make the psf instead of the dirty image
    :param normalize: Normalize by the sum of weights (True)
    """
    log.debug("invert_wstack_single: predicting using single w slice")
    
    kwargs['imaginary'] = True
    
    assert type(vis) == Visibility
    
    # We might want to do wprojection so we remove the average w
    w_average = numpy.average(vis.w)
    vis.data['uvw'][...,2] -= w_average
    reWorkimage, sumwt, imWorkimage = invert_inner(vis, im, dopsf, normalize=normalize, **kwargs)
    vis.data['uvw'][...,2] += w_average

    # Calculate w beam and apply to the model. The imaginary part is not needed
    w_beam = create_w_term_like(im, w_average, vis.phasecentre)
    reWorkimage.data = w_beam.data.real * reWorkimage.data - w_beam.data.imag * imWorkimage.data
    
    return reWorkimage, sumwt
Esempio n. 2
0
 def test_convert_image_to_kernel(self):
     m31image = create_test_image(cellsize=0.001, frequency=[1e8], canonical=True)
     screen = create_w_term_like(m31image, w=20000.0, remove_shift=True)
     screen_fft = fft_image(screen)
     converted = convert_image_to_kernel(screen_fft, 8, 8)
     assert converted.shape == (1, 1, 8, 8, 8, 8)
     with self.assertRaises(AssertionError):
         converted = convert_image_to_kernel(m31image, 15, 1)
     with self.assertRaises(AssertionError):
         converted = convert_image_to_kernel(m31image, 15, 1000)
Esempio n. 3
0
 def test_create_w_term_image(self):
     m31image = create_test_image(cellsize=0.001)
     im = create_w_term_like(m31image, w=20000.0, remove_shift=True)
     im.data = im.data.real
     for x in [64, 64 + 128]:
         for y in [64, 64 + 128]:
             self.assertAlmostEqual(im.data[0, 0, y, x], 0.84946344276442431, 7)
     export_image_to_fits(im, '%s/test_wterm.fits' % self.dir)
     assert im.data.shape == (1, 1, 256, 256)
     self.assertAlmostEqual(numpy.max(im.data.real), 1.0, 7)
def predict_wstack_single(vis, model, remove=True, **kwargs) -> Visibility:
    """ Predict using a single w slices.
    
    This processes a single w plane, rotating out the w beam for the average w

    :param vis: Visibility to be predicted
    :param model: model image
    :return: resulting visibility (in place works)
    """

    if not isinstance(vis, Visibility):
        log.debug("predict_wstack_single: Coalescing")
        avis = coalesce_visibility(vis, **kwargs)
    else:
        avis = vis

    log.debug("predict_wstack_single: predicting using single w slice")

    avis.data['vis'] *= 0.0
    # We might want to do wprojection so we remove the average w
    w_average = numpy.average(avis.w)
    avis.data['uvw'][..., 2] -= w_average
    tempvis = copy_visibility(avis)

    # Calculate w beam and apply to the model. The imaginary part is not needed
    workimage = copy_image(model)
    w_beam = create_w_term_like(model, w_average, vis.phasecentre)

    # Do the real part
    workimage.data = w_beam.data.real * model.data
    avis = predict_2d_base(avis, workimage, **kwargs)

    # and now the imaginary part
    workimage.data = w_beam.data.imag * model.data
    tempvis = predict_2d_base(tempvis, workimage, **kwargs)
    avis.data['vis'] -= 1j * tempvis.data['vis']

    if not remove:
        avis.data['uvw'][..., 2] += w_average

    if isinstance(vis, BlockVisibility) and isinstance(avis, Visibility):
        log.debug("imaging.predict decoalescing post prediction")
        return decoalesce_visibility(avis)
    else:
        return avis
Esempio n. 5
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