def test_pad_extract(self): for npixel, N2 in [(100, 128), (128, 256), (126, 128)]: # Make a 2D complex image of size (npixel, npixel) centred on (npixel//2, npixel//2) cs = 1 + self._pattern(npixel) # Pad it and extract npixel pixels around the centre cs_pad = pad_mid(cs, N2) # Now create the pattern we expect directly cs2 = 1 + self._pattern(N2) * N2 / npixel # At this point all fields in cs2 and cs_pad should either # be equal or zero. equal = numpy.abs(cs_pad - cs2) < 1e-15 zero = numpy.abs(cs_pad) < 1e-15 assert (equal + zero).all(), "Pad (%d, %d) failed" % (npixel, N2) # And extracting the middle should recover the original data assert_allclose(extract_mid(cs_pad, npixel), cs)
def invert_2d_base_timing(vis: Visibility, im: Image, dopsf: bool = False, normalize: bool = True, **kwargs) \ -> (Image, numpy.ndarray, tuple): """ Invert using 2D convolution function, including w projection optionally Use the image im as a template. Do PSF in a separate call. This is at the bottom of the layering i.e. all transforms are eventually expressed in terms of this function. . Any shifting needed is performed here. :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) :return: resulting image """ opt = get_parameter(kwargs, 'opt', False) if not opt: log.debug('Using original algorithm') else: log.debug('Using optimized algorithm') if not isinstance(vis, Visibility): svis = coalesce_visibility(vis, **kwargs) else: svis = copy_visibility(vis) if dopsf: svis.data['vis'] = numpy.ones_like(svis.data['vis']) svis = shift_vis_to_image(svis, im, tangent=True, inverse=False) nchan, npol, ny, nx = im.data.shape padding = {} if get_parameter(kwargs, "padding", False): padding = {'padding': get_parameter(kwargs, "padding", False)} spectral_mode, vfrequencymap = get_frequency_map(svis, im, opt) polarisation_mode, vpolarisationmap = get_polarisation_map(svis, im) uvw_mode, shape, padding, vuvwmap = get_uvw_map(svis, im, **padding) kernel_name, gcf, vkernellist = get_kernel_list(svis, im, **kwargs) # Optionally pad to control aliasing imgridpad = numpy.zeros( [nchan, npol, int(round(padding * ny)), int(round(padding * nx))], dtype='complex') # Use original algorithm if not opt: time_grid = -time.time() imgridpad, sumwt = convolutional_grid(vkernellist, imgridpad, svis.data['vis'], svis.data['imaging_weight'], vuvwmap, vfrequencymap, vpolarisationmap) time_grid += time.time() # Use optimized algorithm else: time_grid = -time.time() kernel_indices, kernels = vkernellist ks0, ks1, ks2, ks3 = kernels[0].shape kernels_c = numpy.zeros((len(kernels), ks0, ks1, ks2, ks3), dtype=kernels[0].dtype) for i in range(len(kernels)): kernels_c[i, ...] = kernels[i] vfrequencymap_c = numpy.array(vfrequencymap, dtype=numpy.int32) sumwt = numpy.zeros((imgridpad.shape[0], imgridpad.shape[1]), dtype=numpy.float64) convolutional_grid_c(imgridpad, sumwt, native_order(svis.data['vis']), native_order(svis.data['imaging_weight']), native_order(kernels_c), native_order(kernel_indices), native_order(vuvwmap), native_order(vfrequencymap_c)) time_grid += time.time() # Fourier transform the padded grid to image, multiply by the gridding correction # function, and extract the unpadded inner part. # Normalise weights for consistency with transform sumwt /= float(padding * int(round(padding * nx)) * ny) imaginary = get_parameter(kwargs, "imaginary", False) if imaginary: log.debug("invert_2d_base: retaining imaginary part of dirty image") result = extract_mid(ifft(imgridpad) * gcf, npixel=nx) resultreal = create_image_from_array(result.real, im.wcs) resultimag = create_image_from_array(result.imag, im.wcs) if normalize: resultreal = normalize_sumwt(resultreal, sumwt) resultimag = normalize_sumwt(resultimag, sumwt) return resultreal, sumwt, resultimag else: # Use original algorithm if not opt: time_ifft = -time.time() inarr = ifft(imgridpad) time_ifft += time.time() # Use optimized algorithm else: time_ifft = -time.time() inarr = numpy.zeros(imgridpad.shape, dtype=imgridpad.dtype) ifft_c(inarr, imgridpad) time_ifft += time.time() result = extract_mid(numpy.real(inarr) * gcf, npixel=nx) resultimage = create_image_from_array(result, im.wcs) if normalize: resultimage = normalize_sumwt(resultimage, sumwt) return resultimage, sumwt, (time_grid, time_ifft)
def invert_2d_base(vis: Visibility, im: Image, dopsf: bool = False, normalize: bool = True, **kwargs) \ -> (Image, numpy.ndarray): """ Invert using 2D convolution function, including w projection optionally Use the image im as a template. Do PSF in a separate call. This is at the bottom of the layering i.e. all transforms are eventually expressed in terms of this function. . Any shifting needed is performed here. :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) :return: resulting image """ if type(vis) is not Visibility: svis = coalesce_visibility(vis, **kwargs) else: svis = copy_visibility(vis) if dopsf: svis.data['vis'] = numpy.ones_like(svis.data['vis']) svis = shift_vis_to_image(svis, im, tangent=True, inverse=False) nchan, npol, ny, nx = im.data.shape spectral_mode, vfrequencymap = get_frequency_map(svis, im) polarisation_mode, vpolarisationmap = get_polarisation_map( svis, im, **kwargs) uvw_mode, shape, padding, vuvwmap = get_uvw_map(svis, im, **kwargs) kernel_name, gcf, vkernellist = get_kernel_list(svis, im, **kwargs) # Optionally pad to control aliasing imgridpad = numpy.zeros( [nchan, npol, int(round(padding * ny)), int(round(padding * nx))], dtype='complex') imgridpad, sumwt = convolutional_grid(vkernellist, imgridpad, svis.data['vis'], svis.data['imaging_weight'], vuvwmap, vfrequencymap, vpolarisationmap) # Fourier transform the padded grid to image, multiply by the gridding correction # function, and extract the unpadded inner part. # Normalise weights for consistency with transform sumwt /= float(padding * int(round(padding * nx)) * ny) imaginary = get_parameter(kwargs, "imaginary", False) if imaginary: log.debug("invert_2d_base: retaining imaginary part of dirty image") result = extract_mid(ifft(imgridpad) * gcf, npixel=nx) resultreal = create_image_from_array(result.real, im.wcs) resultimag = create_image_from_array(result.imag, im.wcs) if normalize: resultreal = normalize_sumwt(resultreal, sumwt) resultimag = normalize_sumwt(resultimag, sumwt) return resultreal, sumwt, resultimag else: result = extract_mid(numpy.real(ifft(imgridpad)) * gcf, npixel=nx) resultimage = create_image_from_array(result, im.wcs) if normalize: resultimage = normalize_sumwt(resultimage, sumwt) return resultimage, sumwt