Beispiel #1
0
    def test_discretize_modes(self, kernel_type, mode):
        """
        Check if the different modes result in kernels that work with convolve.
        Use only small kernel width, to make the test pass quickly.
        """
        if kernel_type == AiryDisk2DKernel and not HAS_SCIPY:
            pytest.skip("Omitting AiryDisk2DKernel, which requires SciPy")
        if not kernel_type == Ring2DKernel:
            kernel = kernel_type(3)
        else:
            kernel = kernel_type(3, 3 * 0.2)

        if kernel.dimension == 1:
            c1 = convolve_fft(delta_pulse_1D,
                              kernel,
                              boundary='fill',
                              normalize_kernel=False)
            c2 = convolve(delta_pulse_1D,
                          kernel,
                          boundary='fill',
                          normalize_kernel=False)
            assert_almost_equal(c1, c2, decimal=12)
        else:
            c1 = convolve_fft(delta_pulse_2D,
                              kernel,
                              boundary='fill',
                              normalize_kernel=False)
            c2 = convolve(delta_pulse_2D,
                          kernel,
                          boundary='fill',
                          normalize_kernel=False)
            assert_almost_equal(c1, c2, decimal=12)
Beispiel #2
0
    def test_masked_array(self):
        """
        Check whether convolve_fft works with masked arrays.
        """

        # Test masked array
        array = np.array([1., 2., 3.], dtype='float64')
        kernel = np.array([1, 1, 1])
        masked_array = np.ma.masked_array(array, mask=[0, 1, 0])
        result = convolve_fft(masked_array, kernel, boundary='fill',
                              fill_value=0.)
        assert_floatclose(result, [1./2, 2, 3./2])

        # Now test against convolve()
        convolve_result = convolve(masked_array, kernel, boundary='fill',
                              fill_value=0.)
        assert_floatclose(convolve_result, result)

        # Test masked kernel
        array = np.array([1., 2., 3.], dtype='float64')
        kernel = np.array([1, 1, 1])
        masked_kernel = np.ma.masked_array(kernel, mask=[0, 1, 0])
        result = convolve_fft(array, masked_kernel, boundary='fill',
                              fill_value=0.)
        assert_floatclose(result, [1, 2, 1])

        # Now test against convolve()
        convolve_result = convolve(array, masked_kernel, boundary='fill',
                              fill_value=0.)
        assert_floatclose(convolve_result, result)
    def test_padding(self):
        """
        Test that convolve_fft pads to _next_fast_lengths and does not expand all dimensions
        to length of longest side (#11242/#10047).
        """

        # old implementation expanded this to up to 2048**3
        shape = (1, 1226, 518)
        img = np.zeros(shape, dtype='float64')
        img[0, 600:610, 300:304] = 1.0
        kernel = np.zeros((1, 7, 7), dtype='float64')
        kernel[0, 3, 3] = 1.0

        with pytest.warns(AstropyUserWarning,
                          match="psf_pad was set to False, which overrides the boundary='fill'"):
            img_fft = convolve_fft(img, kernel, return_fft=True, psf_pad=False, fft_pad=False)
            assert_array_equal(img_fft.shape, shape)
            img_fft = convolve_fft(img, kernel, return_fft=True, psf_pad=False, fft_pad=True)
            # should be from either hardcoded _good_sizes[] or scipy.fft.next_fast_len()
            assert img_fft.shape in ((1, 1250, 540), (1, 1232, 525))

        img_fft = convolve_fft(img, kernel, return_fft=True, psf_pad=True, fft_pad=False)
        assert_array_equal(img_fft.shape, np.array(shape) + np.array(kernel.shape))
        img_fft = convolve_fft(img, kernel, return_fft=True, psf_pad=True, fft_pad=True)
        assert img_fft.shape in ((2, 1250, 540), (2, 1250, 525))
Beispiel #4
0
    def test_random_data(self, kernel_type, width):
        """
        Test smoothing of an image made of random noise
        """
        if kernel_type == AiryDisk2DKernel and not HAS_SCIPY:
            pytest.skip("Omitting AiryDisk2DKernel, which requires SciPy")
        if not kernel_type == Ring2DKernel:
            kernel = kernel_type(width)
        else:
            kernel = kernel_type(width, width * 0.2)

        if kernel.dimension == 1:
            c1 = convolve_fft(random_data_1D,
                              kernel,
                              boundary='fill',
                              normalize_kernel=False)
            c2 = convolve(random_data_1D,
                          kernel,
                          boundary='fill',
                          normalize_kernel=False)
            assert_almost_equal(c1, c2, decimal=12)
        else:
            c1 = convolve_fft(random_data_2D,
                              kernel,
                              boundary='fill',
                              normalize_kernel=False)
            c2 = convolve(random_data_2D,
                          kernel,
                          boundary='fill',
                          normalize_kernel=False)
            assert_almost_equal(c1, c2, decimal=12)
Beispiel #5
0
    def test_unity_3(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that a unit kernel with three elements returns the same array
        (except when boundary is None).
        '''

        x = np.array([1., 2., 3.], dtype='float64')

        y = np.array([0., 1., 0.], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning,
                              match=r"The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x,
                                 y,
                                 boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x,
                             y,
                             boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel)

        assert_floatclose(z, x)
Beispiel #6
0
    def test_unity_3x3(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that a 3x3 unit kernel returns the same array (except when
        boundary is None).
        '''

        x = np.array([[1., 2., 3.],
                      [4., 5., 6.],
                      [7., 8., 9.]], dtype='float64')

        y = np.array([[0., 0., 0.],
                      [0., 1., 0.],
                      [0., 0., 0.]], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel)

        assert_floatclose(z, x)
Beispiel #7
0
    def test_masked_array(self):
        """
        Check whether convolve_fft works with masked arrays.
        """

        # Test masked array
        array = np.array([1., 2., 3.], dtype='float64')
        kernel = np.array([1, 1, 1])
        masked_array = np.ma.masked_array(array, mask=[0, 1, 0])
        result = convolve_fft(masked_array, kernel, boundary='fill',
                              fill_value=0.)
        assert_floatclose(result, [1./2, 2, 3./2])

        # Now test against convolve()
        convolve_result = convolve(masked_array, kernel, boundary='fill',
                              fill_value=0.)
        assert_floatclose(convolve_result, result)

        # Test masked kernel
        array = np.array([1., 2., 3.], dtype='float64')
        kernel = np.array([1, 1, 1])
        masked_kernel = np.ma.masked_array(kernel, mask=[0, 1, 0])
        result = convolve_fft(array, masked_kernel, boundary='fill',
                              fill_value=0.)
        assert_floatclose(result, [1, 2, 1])

        # Now test against convolve()
        convolve_result = convolve(array, masked_kernel, boundary='fill',
                              fill_value=0.)
        assert_floatclose(convolve_result, result)
    def test_unity_1_withnan(self, boundary, nan_treatment, normalize_kernel,
                             preserve_nan, inval, outval):
        '''
        Test that a unit kernel with three elements returns the same array
        (except when boundary is None). This version includes a NaN value in
        the original array.
        '''

        x = inval

        y = np.array([1.], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match=r"The convolve_fft "
                              r"version of boundary=None is equivalent to the "
                              r"convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel,
                                 preserve_nan=preserve_nan)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel,
                             preserve_nan=preserve_nan)

        if preserve_nan:
            assert np.isnan(z[1])

        z = np.nan_to_num(z)

        assert_floatclose(z, outval)
    def test_non_normalized_kernel(self, boundary):

        x = np.array([[0., 0., 4.],
                      [1., 2., 0.],
                      [0., 3., 0.]], dtype='float')

        y = np.array([[1., -1., 1.],
                      [-1., 0., -1.],
                      [1., -1., 1.]], dtype='float')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match=r"The convolve_fft "
                              r"version of boundary=None is equivalent to the "
                              r"convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary, nan_treatment='fill',
                                 normalize_kernel=False)
        else:
            z = convolve_fft(x, y, boundary=boundary, nan_treatment='fill',
                             normalize_kernel=False)

        if boundary in (None, 'fill'):
            assert_floatclose(z, np.array([[1., -5., 2.],
                                           [1., 0., -3.],
                                           [-2., -1., -1.]], dtype='float'))
        elif boundary == 'wrap':
            assert_floatclose(z, np.array([[0., -8., 6.],
                                           [5., 0., -4.],
                                           [2., 3., -4.]], dtype='float'))
        else:
            raise ValueError("Invalid boundary specification")
Beispiel #10
0
def test_asymmetric_kernel(boundary):
    '''
    Make sure that asymmetric convolution
    functions go the right direction
    '''

    x = np.array([3., 0., 1.], dtype='>f8')

    y = np.array([1, 2, 3], dtype='>f8')

    if boundary is None:
        with pytest.warns(AstropyUserWarning,
                          match=r"The convolve_fft "
                          "version of boundary=None is equivalent to the "
                          "convolve boundary='fill'"):
            z = convolve_fft(x, y, boundary=boundary, normalize_kernel=False)
    else:
        z = convolve_fft(x, y, boundary=boundary, normalize_kernel=False)

    if boundary in (None, 'fill'):
        assert_array_almost_equal_nulp(z, np.array([6., 10., 2.],
                                                   dtype='float'), 10)
    elif boundary == 'wrap':
        assert_array_almost_equal_nulp(z, np.array([9., 10., 5.],
                                                   dtype='float'), 10)
Beispiel #11
0
    def test_unity_1_withnan(self, boundary, nan_treatment, normalize_kernel,
                             preserve_nan, inval, outval):
        '''
        Test that a unit kernel with three elements returns the same array
        (except when boundary is None). This version includes a NaN value in
        the original array.
        '''

        x = inval

        y = np.array([1.], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel,
                                 preserve_nan=preserve_nan)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel,
                             preserve_nan=preserve_nan)

        if preserve_nan:
            assert np.isnan(z[1])

        z = np.nan_to_num(z)

        assert_floatclose(z, outval)
Beispiel #12
0
    def test_non_normalized_kernel(self, boundary):

        x = np.array([[0., 0., 4.],
                      [1., 2., 0.],
                      [0., 3., 0.]], dtype='float')

        y = np.array([[1., -1., 1.],
                      [-1., 0., -1.],
                      [1., -1., 1.]], dtype='float')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary, nan_treatment='fill',
                                 normalize_kernel=False)
        else:
            z = convolve_fft(x, y, boundary=boundary, nan_treatment='fill',
                             normalize_kernel=False)

        if boundary in (None, 'fill'):
            assert_floatclose(z, np.array([[1., -5., 2.],
                                           [1., 0., -3.],
                                           [-2., -1., -1.]], dtype='float'))
        elif boundary == 'wrap':
            assert_floatclose(z, np.array([[0., -8., 6.],
                                           [5., 0., -4.],
                                           [2., 3., -4.]], dtype='float'))
        else:
            raise ValueError("Invalid boundary specification")
Beispiel #13
0
    def test_unity_1x1_none(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that a 1x1 unit kernel returns the same array
        '''

        x = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]],
                     dtype='float64')

        y = np.array([[1.]], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning,
                              match=r"The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x,
                                 y,
                                 boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x,
                             y,
                             boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel)

        assert_floatclose(z, x)
Beispiel #14
0
def test_convolve_fft_boundary_extend_error():
    x = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]], dtype='>f8')
    y = np.array([[1.]], dtype='>f8')

    with pytest.raises(NotImplementedError) as err:
        convolve_fft(x, y, boundary='extend')
    assert str(err.value) == \
        "The 'extend' option is not implemented for fft-based convolution"
Beispiel #15
0
    def test_uniform_3x3(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that the different modes are producing the correct results using
        a 3x3 uniform kernel.
        '''

        x = np.array([[0., 0., 3.], [1., 0., 0.], [0., 2., 0.]],
                     dtype='float64')

        y = np.array([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]],
                     dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning,
                              match=r"The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x,
                                 y,
                                 boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 fill_value=np.nan if normalize_kernel else 0,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x,
                             y,
                             boundary=boundary,
                             nan_treatment=nan_treatment,
                             fill_value=np.nan if normalize_kernel else 0,
                             normalize_kernel=normalize_kernel)

        w = np.array([[4., 6., 4.], [6., 9., 6.], [4., 6., 4.]],
                     dtype='float64')
        answer_dict = {
            'sum':
            np.array([[1., 4., 3.], [3., 6., 5.], [3., 3., 2.]],
                     dtype='float64'),
            'sum_wrap':
            np.array([[6., 6., 6.], [6., 6., 6.], [6., 6., 6.]],
                     dtype='float64'),
        }
        answer_dict['average'] = answer_dict['sum'] / w
        answer_dict['average_wrap'] = answer_dict['sum_wrap'] / 9.
        answer_dict['average_withzeros'] = answer_dict['sum'] / 9.
        answer_dict['sum_withzeros'] = answer_dict['sum']

        if normalize_kernel:
            answer_key = 'average'
        else:
            answer_key = 'sum'

        if boundary == 'wrap':
            answer_key += '_wrap'
        elif nan_treatment == 'fill':
            answer_key += '_withzeros'

        a = answer_dict[answer_key]
        assert_floatclose(z, a)
Beispiel #16
0
def test_convolve_fft_boundary_wrap_error(error_kwarg):
    x = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]], dtype='>f8')
    y = np.array([[1.]], dtype='>f8')
    assert (convolve_fft(x, y, boundary='wrap') == x).all()

    with pytest.raises(ValueError) as err:
        convolve_fft(x, y, boundary='wrap', **error_kwarg)
    assert str(err.value) == \
        f"With boundary='wrap', {list(error_kwarg.keys())[0]} cannot be enabled."
Beispiel #17
0
    def test_uniform_3(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that the different modes are producing the correct results using
        a uniform kernel with three elements
        '''

        x = np.array([1., 0., 3.], dtype='float64')

        y = np.array([1., 1., 1.], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning,
                              match=r"The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x,
                                 y,
                                 boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x,
                             y,
                             boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel)

        answer_key = (boundary, nan_treatment, normalize_kernel)

        answer_dict = {
            'sum_fill_zeros': np.array([1., 4., 3.], dtype='float64'),
            'average_fill_zeros': np.array([1 / 3., 4 / 3., 1.],
                                           dtype='float64'),
            'sum_wrap': np.array([4., 4., 4.], dtype='float64'),
            'average_wrap': np.array([4 / 3., 4 / 3., 4 / 3.],
                                     dtype='float64'),
        }

        result_dict = {
            # boundary, nan_treatment, normalize_kernel
            ('fill', 'interpolate', True):
            answer_dict['average_fill_zeros'],
            ('wrap', 'interpolate', True):
            answer_dict['average_wrap'],
            ('fill', 'interpolate', False):
            answer_dict['sum_fill_zeros'],
            ('wrap', 'interpolate', False):
            answer_dict['sum_wrap'],
        }
        for k in list(result_dict.keys()):
            result_dict[(k[0], 'fill', k[2])] = result_dict[k]
        for k in list(result_dict.keys()):
            if k[0] == 'fill':
                result_dict[(None, k[1], k[2])] = result_dict[k]

        assert_floatclose(z, result_dict[answer_key])
Beispiel #18
0
    def test_uniform_3x3(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that the different modes are producing the correct results using
        a 3x3 uniform kernel.
        '''

        x = np.array([[0., 0., 3.],
                      [1., 0., 0.],
                      [0., 2., 0.]], dtype='float64')

        y = np.array([[1., 1., 1.],
                      [1., 1., 1.],
                      [1., 1., 1.]], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 fill_value=np.nan if normalize_kernel else 0,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             fill_value=np.nan if normalize_kernel else 0,
                             normalize_kernel=normalize_kernel)

        w = np.array([[4., 6., 4.],
                      [6., 9., 6.],
                      [4., 6., 4.]], dtype='float64')
        answer_dict = {
            'sum': np.array([[1., 4., 3.],
                             [3., 6., 5.],
                             [3., 3., 2.]], dtype='float64'),
            'sum_wrap': np.array([[6., 6., 6.],
                                  [6., 6., 6.],
                                  [6., 6., 6.]], dtype='float64'),
        }
        answer_dict['average'] = answer_dict['sum'] / w
        answer_dict['average_wrap'] = answer_dict['sum_wrap'] / 9.
        answer_dict['average_withzeros'] = answer_dict['sum'] / 9.
        answer_dict['sum_withzeros'] = answer_dict['sum']

        if normalize_kernel:
            answer_key = 'average'
        else:
            answer_key = 'sum'

        if boundary == 'wrap':
            answer_key += '_wrap'
        elif nan_treatment == 'fill':
            answer_key += '_withzeros'

        a = answer_dict[answer_key]
        assert_floatclose(z, a)
Beispiel #19
0
    def test_big_fail(self):
        """ Test that convolve_fft raises an exception if a too-large array is passed in """

        with pytest.raises((ValueError, MemoryError)):
            # while a good idea, this approach did not work; it actually writes to disk
            # arr = np.memmap('file.np', mode='w+', shape=(512, 512, 512), dtype=complex)
            # this just allocates the memory but never touches it; it's better:
            arr = np.empty([512, 512, 512], dtype=complex)
            # note 512**3 * 16 bytes = 2.0 GB
            convolve_fft(arr, arr)
Beispiel #20
0
    def test_big_fail(self):
        """ Test that convolve_fft raises an exception if a too-large array is passed in """

        with pytest.raises((ValueError, MemoryError)):
            # while a good idea, this approach did not work; it actually writes to disk
            # arr = np.memmap('file.np', mode='w+', shape=(512, 512, 512), dtype=complex)
            # this just allocates the memory but never touches it; it's better:
            arr = np.empty([512, 512, 512], dtype=complex)
            # note 512**3 * 16 bytes = 2.0 GB
            convolve_fft(arr, arr)
Beispiel #21
0
    def test_smallkernel_vs_Box2DKernel(self, width):
        """
        Test smoothing of an image with a single positive pixel
        """
        kernel1 = np.ones([width, width]) / width**2
        kernel2 = Box2DKernel(width)

        c2 = convolve_fft(delta_pulse_2D, kernel2, boundary='fill')
        c1 = convolve_fft(delta_pulse_2D, kernel1, boundary='fill')

        assert_almost_equal(c1, c2, decimal=12)
Beispiel #22
0
    def test_halfity_3(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that the different modes are producing the correct results using
        a uniform, non-unity kernel with three elements
        '''

        x = np.array([1., 0., 3.], dtype='float64')

        y = np.array([0.5, 0.5, 0.5], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning,
                              match=r"The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x,
                                 y,
                                 boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x,
                             y,
                             boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel)

        answer_dict = {
            'sum': np.array([0.5, 2.0, 1.5], dtype='float64'),
            'sum_zeros': np.array([0.5, 2., 1.5], dtype='float64'),
            'sum_nozeros': np.array([0.5, 2., 1.5], dtype='float64'),
            'average': np.array([1 / 3., 4 / 3., 1.], dtype='float64'),
            'sum_wrap': np.array([2., 2., 2.], dtype='float64'),
            'average_wrap': np.array([4 / 3., 4 / 3., 4 / 3.],
                                     dtype='float64'),
            'average_zeros': np.array([1 / 3., 4 / 3., 1.], dtype='float64'),
            'average_nozeros': np.array([0.5, 4 / 3., 1.5], dtype='float64'),
        }

        if normalize_kernel:
            answer_key = 'average'
        else:
            answer_key = 'sum'

        if boundary == 'wrap':
            answer_key += '_wrap'
        else:
            # average = average_zeros; sum = sum_zeros
            answer_key += '_zeros'

        assert_floatclose(z, answer_dict[answer_key])
Beispiel #23
0
def test_input_unmodified(boundary, nan_treatment, normalize_kernel,
                          preserve_nan, dtype):
    """
    Test that convolve_fft works correctly when inputs are lists
    """

    array = [1., 4., 5., 6., 5., 7., 8.]
    kernel = [0.2, 0.6, 0.2]
    x = np.array(array, dtype=dtype)
    y = np.array(kernel, dtype=dtype)

    # Make pseudoimmutable
    x.flags.writeable = False
    y.flags.writeable = False

    with expected_boundary_warning(boundary=boundary):
        z = convolve_fft(x,
                         y,
                         boundary=boundary,
                         nan_treatment=nan_treatment,
                         normalize_kernel=normalize_kernel,
                         preserve_nan=preserve_nan)

    assert np.all(np.array(array, dtype=dtype) == x)
    assert np.all(np.array(kernel, dtype=dtype) == y)
Beispiel #24
0
    def test_non_normalized_kernel(self, boundary):

        x = np.array([[0., 0., 4.], [1., 2., 0.], [0., 3., 0.]], dtype='float')

        y = np.array([[1., -1., 1.], [-1., 0., -1.], [1., -1., 1.]],
                     dtype='float')

        with expected_boundary_warning(boundary=boundary):
            z = convolve_fft(x,
                             y,
                             boundary=boundary,
                             nan_treatment='fill',
                             normalize_kernel=False)

        if boundary in (None, 'fill'):
            assert_floatclose(
                z,
                np.array([[1., -5., 2.], [1., 0., -3.], [-2., -1., -1.]],
                         dtype='float'))
        elif boundary == 'wrap':
            assert_floatclose(
                z,
                np.array([[0., -8., 6.], [5., 0., -4.], [2., 3., -4.]],
                         dtype='float'))
        else:
            raise ValueError("Invalid boundary specification")
Beispiel #25
0
    def test_normalization_is_respected(self, boundary,
                                        nan_treatment,
                                        normalize_kernel):
        """
        Check that if normalize_kernel is False then the normalization
        tolerance is respected.
        """
        array = np.array([1, 2, 3])
        # A simple identity kernel to which a non-zero normalization is added.
        base_kernel = np.array([1.0])

        # Use the same normalization error tolerance in all cases.
        normalization_rtol = 1e-4

        # Add the error below to the kernel.
        norm_error = [normalization_rtol / 10, normalization_rtol * 10]

        for err in norm_error:
            kernel = base_kernel + err
            result = convolve_fft(array, kernel,
                                  normalize_kernel=normalize_kernel,
                                  nan_treatment=nan_treatment,
                                  normalization_zero_tol=normalization_rtol)
            if normalize_kernel:
                # Kernel has been normalized to 1.
                assert_floatclose(result, array)
            else:
                # Kernel should not have been normalized...
                assert_floatclose(result, array * kernel)
Beispiel #26
0
    def test_unity_3x3_withnan(self, boundary, nan_treatment,
                               normalize_kernel, preserve_nan):
        '''
        Test that a 3x3 unit kernel returns the same array (except when
        boundary is None). This version includes a NaN value in the original
        array.
        '''

        x = np.array([[1., 2., 3.],
                      [4., np.nan, 6.],
                      [7., 8., 9.]], dtype='float64')

        y = np.array([[0., 0., 0.],
                      [0., 1., 0.],
                      [0., 0., 0.]], dtype='float64')

        with expected_boundary_warning(boundary=boundary):
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel,
                             preserve_nan=preserve_nan)

        if preserve_nan:
            assert np.isnan(z[1, 1])
            z = np.nan_to_num(z)

        x = np.nan_to_num(x)

        assert_floatclose(z, x)
Beispiel #27
0
    def test_normalization_is_respected(self, boundary,
                                        nan_treatment,
                                        normalize_kernel):
        """
        Check that if normalize_kernel is False then the normalization
        tolerance is respected.
        """
        array = np.array([1, 2, 3])
        # A simple identity kernel to which a non-zero normalization is added.
        base_kernel = np.array([1.0])

        # Use the same normalization error tolerance in all cases.
        normalization_rtol = 1e-4

        # Add the error below to the kernel.
        norm_error = [normalization_rtol / 10, normalization_rtol * 10]

        for err in norm_error:
            kernel = base_kernel + err
            result = convolve_fft(array, kernel,
                                  normalize_kernel=normalize_kernel,
                                  nan_treatment=nan_treatment,
                                  normalization_zero_tol=normalization_rtol)
            if normalize_kernel:
                # Kernel has been normalized to 1.
                assert_floatclose(result, array)
            else:
                # Kernel should not have been normalized...
                assert_floatclose(result, array * kernel)
Beispiel #28
0
def test_input_unmodified_with_nan(boundary, nan_treatment,
                                   normalize_kernel, preserve_nan, dtype):
    """
    Test that convolve_fft doesn't modify the input data
    """

    array = [1., 4., 5., np.nan, 5., 7., 8.]
    kernel = [0.2, 0.6, 0.2]
    x = np.array(array, dtype=dtype)
    y = np.array(kernel, dtype=dtype)

    # Make pseudoimmutable
    x.flags.writeable = False
    y.flags.writeable = False

    # make copies for post call comparison
    x_copy = x.copy()
    y_copy = y.copy()

    z = convolve_fft(x, y, boundary=boundary, nan_treatment=nan_treatment,
                 normalize_kernel=normalize_kernel, preserve_nan=preserve_nan)

    # ( NaN == NaN ) = False
    # Only compare non NaN values for canonical equivalence
    # and then check NaN explicitly with np.isnan()
    array_is_nan = np.isnan(array)
    kernel_is_nan = np.isnan(kernel)
    array_not_nan = ~array_is_nan
    kernel_not_nan = ~kernel_is_nan
    assert np.all(x_copy[array_not_nan] == x[array_not_nan])
    assert np.all(y_copy[kernel_not_nan] == y[kernel_not_nan])
    assert np.all(np.isnan(x[array_is_nan]))
    assert np.all(np.isnan(y[kernel_is_nan]))
Beispiel #29
0
def test_input_unmodified_with_nan(boundary, nan_treatment,
                                   normalize_kernel, preserve_nan, dtype):
    """
    Test that convolve_fft doesn't modify the input data
    """

    array = [1., 4., 5., np.nan, 5., 7., 8.]
    kernel = [0.2, 0.6, 0.2]
    x = np.array(array, dtype=dtype)
    y = np.array(kernel, dtype=dtype)

    # Make pseudoimmutable
    x.flags.writeable = False
    y.flags.writeable = False

    # make copies for post call comparison
    x_copy = x.copy()
    y_copy = y.copy()

    with expected_boundary_warning(boundary=boundary):
        z = convolve_fft(x, y, boundary=boundary, nan_treatment=nan_treatment,
                        normalize_kernel=normalize_kernel, preserve_nan=preserve_nan)

    # ( NaN == NaN ) = False
    # Only compare non NaN values for canonical equivalence
    # and then check NaN explicitly with np.isnan()
    array_is_nan = np.isnan(array)
    kernel_is_nan = np.isnan(kernel)
    array_not_nan = ~array_is_nan
    kernel_not_nan = ~kernel_is_nan
    assert np.all(x_copy[array_not_nan] == x[array_not_nan])
    assert np.all(y_copy[kernel_not_nan] == y[kernel_not_nan])
    assert np.all(np.isnan(x[array_is_nan]))
    assert np.all(np.isnan(y[kernel_is_nan]))
Beispiel #30
0
    def test_unity_1_withnan(self, boundary, nan_treatment, normalize_kernel,
                             preserve_nan, inval, outval):
        '''
        Test that a unit kernel with three elements returns the same array
        (except when boundary is None). This version includes a NaN value in
        the original array.
        '''

        x = inval

        y = np.array([1.], dtype='float64')

        with expected_boundary_warning(boundary=boundary):
            z = convolve_fft(x,
                             y,
                             boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel,
                             preserve_nan=preserve_nan)

        if preserve_nan:
            assert np.isnan(z[1])

        z = np.nan_to_num(z)

        assert_floatclose(z, outval)
Beispiel #31
0
def test_astropy_convolution_against_numpy():
    x = np.array([1, 2, 3])
    y = np.array([5, 4, 3, 2, 1])

    assert_array_almost_equal(np.convolve(y, x, 'same'),
                              convolve(y, x, normalize_kernel=False))
    assert_array_almost_equal(np.convolve(y, x, 'same'),
                              convolve_fft(y, x, normalize_kernel=False))
Beispiel #32
0
def test_astropy_convolution_against_numpy():
    x = np.array([1, 2, 3])
    y = np.array([5, 4, 3, 2, 1])

    assert_array_almost_equal(np.convolve(y, x, 'same'),
                              convolve(y, x, normalize_kernel=False))
    assert_array_almost_equal(np.convolve(y, x, 'same'),
                              convolve_fft(y, x, normalize_kernel=False))
Beispiel #33
0
 def test_normalize_function(self):
     """
     Check if convolve_fft works when passing a normalize function.
     """
     array = [1, 2, 3]
     kernel = [3, 3, 3]
     result = convolve_fft(array, kernel, normalize_kernel=np.max)
     assert_floatclose(result, [3, 6, 5])
Beispiel #34
0
 def test_normalize_function(self):
     """
     Check if convolve_fft works when passing a normalize function.
     """
     array = [1, 2, 3]
     kernel = [3, 3, 3]
     result = convolve_fft(array, kernel, normalize_kernel=np.max)
     assert_floatclose(result, [3, 6, 5])
Beispiel #35
0
    def test_halfity_3(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that the different modes are producing the correct results using
        a uniform, non-unity kernel with three elements
        '''

        x = np.array([1., 0., 3.], dtype='float64')

        y = np.array([0.5, 0.5, 0.5], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel)

        answer_dict = {
            'sum': np.array([0.5, 2.0, 1.5], dtype='float64'),
            'sum_zeros': np.array([0.5, 2., 1.5], dtype='float64'),
            'sum_nozeros': np.array([0.5, 2., 1.5], dtype='float64'),
            'average': np.array([1 / 3., 4 / 3., 1.], dtype='float64'),
            'sum_wrap': np.array([2., 2., 2.], dtype='float64'),
            'average_wrap': np.array([4 / 3., 4 / 3., 4 / 3.], dtype='float64'),
            'average_zeros': np.array([1 / 3., 4 / 3., 1.], dtype='float64'),
            'average_nozeros': np.array([0.5, 4 / 3., 1.5], dtype='float64'),
        }

        if normalize_kernel:
            answer_key = 'average'
        else:
            answer_key = 'sum'

        if boundary == 'wrap':
            answer_key += '_wrap'
        else:
            # average = average_zeros; sum = sum_zeros
            answer_key += '_zeros'

        assert_floatclose(z, answer_dict[answer_key])
Beispiel #36
0
    def test_uniform_3(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that the different modes are producing the correct results using
        a uniform kernel with three elements
        '''

        x = np.array([1., 0., 3.], dtype='float64')

        y = np.array([1., 1., 1.], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel)

        answer_key = (boundary, nan_treatment, normalize_kernel)

        answer_dict = {
            'sum_fill_zeros': np.array([1., 4., 3.], dtype='float64'),
            'average_fill_zeros': np.array([1 / 3., 4 / 3., 1.], dtype='float64'),
            'sum_wrap': np.array([4., 4., 4.], dtype='float64'),
            'average_wrap': np.array([4 / 3., 4 / 3., 4 / 3.], dtype='float64'),
        }

        result_dict = {
            # boundary, nan_treatment, normalize_kernel
            ('fill', 'interpolate', True): answer_dict['average_fill_zeros'],
            ('wrap', 'interpolate', True): answer_dict['average_wrap'],
            ('fill', 'interpolate', False): answer_dict['sum_fill_zeros'],
            ('wrap', 'interpolate', False): answer_dict['sum_wrap'],
        }
        for k in list(result_dict.keys()):
            result_dict[(k[0], 'fill', k[2])] = result_dict[k]
        for k in list(result_dict.keys()):
            if k[0] == 'fill':
                result_dict[(None, k[1], k[2])] = result_dict[k]

        assert_floatclose(z, result_dict[answer_key])
Beispiel #37
0
def test_astropy_convolution_against_scipy():
    from scipy.signal import fftconvolve
    x = np.array([1, 2, 3])
    y = np.array([5, 4, 3, 2, 1])

    assert_array_almost_equal(fftconvolve(y, x, 'same'),
                              convolve(y, x, normalize_kernel=False))
    assert_array_almost_equal(fftconvolve(y, x, 'same'),
                              convolve_fft(y, x, normalize_kernel=False))
Beispiel #38
0
    def test_nan_fill(self):

        # Test masked array
        array = np.array([1., np.nan, 3.], dtype='float64')
        kernel = np.array([1, 1, 1])
        masked_array = np.ma.masked_array(array, mask=[0, 1, 0])
        result = convolve_fft(masked_array, kernel, boundary='fill',
                              fill_value=np.nan)
        assert_floatclose(result, [1, 2, 3])
Beispiel #39
0
def test_astropy_convolution_against_scipy():
    from scipy.signal import fftconvolve
    x = np.array([1, 2, 3])
    y = np.array([5, 4, 3, 2, 1])

    assert_array_almost_equal(fftconvolve(y, x, 'same'),
                              convolve(y, x, normalize_kernel=False))
    assert_array_almost_equal(fftconvolve(y, x, 'same'),
                              convolve_fft(y, x, normalize_kernel=False))
Beispiel #40
0
    def test_uniform_smallkernel(self, width):
        """
        Test smoothing of an image with a single positive pixel

        Instead of using kernel class, uses a simple, small kernel
        """
        kernel = np.ones([width, width])

        c2 = convolve_fft(delta_pulse_2D, kernel, boundary='fill')
        c1 = convolve(delta_pulse_2D, kernel, boundary='fill')
        assert_almost_equal(c1, c2, decimal=12)
Beispiel #41
0
    def test_nan_fill(self):

        # Test masked array
        array = np.array([1., np.nan, 3.], dtype='float64')
        kernel = np.array([1, 1, 1])
        masked_array = np.ma.masked_array(array, mask=[0, 1, 0])
        result = convolve_fft(masked_array,
                              kernel,
                              boundary='fill',
                              fill_value=np.nan)
        assert_floatclose(result, [1, 2, 3])
Beispiel #42
0
def test_convolution_consistency(ndims):

    np.random.seed(0)
    array = np.random.randn(*([3] * ndims))
    np.random.seed(0)
    kernel = np.random.rand(*([3] * ndims))

    conv_f = convolve_fft(array, kernel, boundary='fill')
    conv_d = convolve(array, kernel, boundary='fill')

    assert_array_almost_equal_nulp(conv_f, conv_d, 30)
Beispiel #43
0
def test_convolution_consistency(ndims):

    np.random.seed(0)
    array = np.random.randn(*([3]*ndims))
    np.random.seed(0)
    kernel = np.random.rand(*([3]*ndims))

    conv_f = convolve_fft(array, kernel, boundary='fill')
    conv_d = convolve(array, kernel, boundary='fill')

    assert_array_almost_equal_nulp(conv_f, conv_d, 30)
Beispiel #44
0
    def test_unity_3x3_withnan(self, boundary, nan_treatment, normalize_kernel,
                               preserve_nan):
        '''
        Test that a 3x3 unit kernel returns the same array (except when
        boundary is None). This version includes a NaN value in the original
        array.
        '''

        x = np.array([[1., 2., 3.], [4., np.nan, 6.], [7., 8., 9.]],
                     dtype='float64')

        y = np.array([[0., 0., 0.], [0., 1., 0.], [0., 0., 0.]],
                     dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning,
                              match=r"The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x,
                                 y,
                                 boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel,
                                 preserve_nan=preserve_nan)
        else:
            z = convolve_fft(x,
                             y,
                             boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel,
                             preserve_nan=preserve_nan)

        if preserve_nan:
            assert np.isnan(z[1, 1])
            z = np.nan_to_num(z)

        x = np.nan_to_num(x)

        assert_floatclose(z, x)
Beispiel #45
0
def test_asymmetric_kernel(boundary):
    '''
    Make sure that asymmetric convolution
    functions go the right direction
    '''

    x = np.array([3., 0., 1.], dtype='>f8')

    y = np.array([1, 2, 3], dtype='>f8')

    if boundary is None:
        with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                          "version of boundary=None is equivalent to the "
                          "convolve boundary='fill'"):
            z = convolve_fft(x, y, boundary=boundary, normalize_kernel=False)
    else:
        z = convolve_fft(x, y, boundary=boundary, normalize_kernel=False)

    if boundary in (None, 'fill'):
        assert_array_almost_equal_nulp(z, np.array([6., 10., 2.], dtype='float'), 10)
    elif boundary == 'wrap':
        assert_array_almost_equal_nulp(z, np.array([9., 10., 5.], dtype='float'), 10)
Beispiel #46
0
    def test_unity_1_none(self, boundary, nan_treatment, normalize_kernel):
        '''
        Test that a unit kernel with a single element returns the same array
        '''

        x = np.array([1., 2., 3.], dtype='float64')

        y = np.array([1.], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel)

        assert_floatclose(z, x)
Beispiel #47
0
    def test_halfity_3(self, boundary, nan_treatment, normalize_kernel,
                       dealias):
        '''
        Test that the different modes are producing the correct results using
        a uniform, non-unity kernel with three elements
        '''

        x = np.array([1., 0., 3.], dtype='float64')

        y = np.array([0.5, 0.5, 0.5], dtype='float64')

        with expected_boundary_warning(boundary=boundary):
            with expected_dealias_error(boundary=boundary, dealias=dealias):
                z = convolve_fft(x,
                                 y,
                                 boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel,
                                 dealias=dealias)

                answer_dict = {
                    'sum':
                    np.array([0.5, 2.0, 1.5], dtype='float64'),
                    'sum_zeros':
                    np.array([0.5, 2., 1.5], dtype='float64'),
                    'sum_nozeros':
                    np.array([0.5, 2., 1.5], dtype='float64'),
                    'average':
                    np.array([1 / 3., 4 / 3., 1.], dtype='float64'),
                    'sum_wrap':
                    np.array([2., 2., 2.], dtype='float64'),
                    'average_wrap':
                    np.array([4 / 3., 4 / 3., 4 / 3.], dtype='float64'),
                    'average_zeros':
                    np.array([1 / 3., 4 / 3., 1.], dtype='float64'),
                    'average_nozeros':
                    np.array([0.5, 4 / 3., 1.5], dtype='float64'),
                }

                if normalize_kernel:
                    answer_key = 'average'
                else:
                    answer_key = 'sum'

                if boundary == 'wrap':
                    answer_key += '_wrap'
                else:
                    # average = average_zeros; sum = sum_zeros
                    answer_key += '_zeros'

                assert_floatclose(z, answer_dict[answer_key])
Beispiel #48
0
    def test_smallkernel_Box2DKernel(self, shape, width):
        """
        Test smoothing of an image with a single positive pixel

        Compares a small uniform kernel to the Box2DKernel
        """

        kernel1 = np.ones([width, width]) / float(width) ** 2
        kernel2 = Box2DKernel(width, mode='oversample', factor=10)

        x = np.zeros(shape)
        xslice = tuple([slice(sh // 2, sh // 2 + 1) for sh in shape])
        x[xslice] = 1.0

        c2 = convolve_fft(x, kernel2, boundary='fill')
        c1 = convolve_fft(x, kernel1, boundary='fill')

        assert_almost_equal(c1, c2, decimal=12)

        c2 = convolve(x, kernel2, boundary='fill')
        c1 = convolve(x, kernel1, boundary='fill')

        assert_almost_equal(c1, c2, decimal=12)
Beispiel #49
0
    def test_random_makekernel(self, kernel):
        """
        Test smoothing of an image made of random noise
        """

        shape = kernel.array.shape

        x = np.random.randn(*shape)

        c2 = convolve_fft(x, kernel, boundary='fill')
        c1 = convolve(x, kernel, boundary='fill')

        # not clear why, but these differ by a couple ulps...
        assert_almost_equal(c1, c2, decimal=12)
Beispiel #50
0
    def test_unity_3x3_withnan(self, boundary, nan_treatment,
                               normalize_kernel, preserve_nan):
        '''
        Test that a 3x3 unit kernel returns the same array (except when
        boundary is None). This version includes a NaN value in the original
        array.
        '''

        x = np.array([[1., 2., 3.],
                      [4., np.nan, 6.],
                      [7., 8., 9.]], dtype='float64')

        y = np.array([[0., 0., 0.],
                      [0., 1., 0.],
                      [0., 0., 0.]], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel,
                                 preserve_nan=preserve_nan)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel,
                             preserve_nan=preserve_nan)

        if preserve_nan:
            assert np.isnan(z[1, 1])
            z = np.nan_to_num(z)

        x = np.nan_to_num(x)

        assert_floatclose(z, x)
Beispiel #51
0
def test_basic_nddata():
    arr = np.zeros((11, 11))
    arr[5, 5] = 1
    ndd = NDData(arr)
    test_kernel = Gaussian2DKernel(1)

    result = convolve(ndd, test_kernel)

    x, y = np.mgrid[:11, :11]
    expected = result[5, 5] * np.exp(-0.5 * ((x - 5)**2 + (y - 5)**2))

    np.testing.assert_allclose(result, expected, atol=1e-6)

    resultf = convolve_fft(ndd, test_kernel)
    np.testing.assert_allclose(resultf, expected, atol=1e-6)
Beispiel #52
0
    def test_centered_makekernel(self, kernel):
        """
        Test smoothing of an image with a single positive pixel
        """

        shape = kernel.array.shape

        x = np.zeros(shape)
        xslice = tuple([slice(sh // 2, sh // 2 + 1) for sh in shape])
        x[xslice] = 1.0

        c2 = convolve_fft(x, kernel, boundary='fill')
        c1 = convolve(x, kernel, boundary='fill')

        assert_almost_equal(c1, c2, decimal=12)
Beispiel #53
0
def test_input_unmodified(boundary, nan_treatment,
                          normalize_kernel, preserve_nan, dtype):
    """
    Test that convolve_fft works correctly when inputs are lists
    """

    array = [1., 4., 5., 6., 5., 7., 8.]
    kernel = [0.2, 0.6, 0.2]
    x = np.array(array, dtype=dtype)
    y = np.array(kernel, dtype=dtype)

    # Make pseudoimmutable
    x.flags.writeable = False
    y.flags.writeable = False

    z = convolve_fft(x, y, boundary=boundary, nan_treatment=nan_treatment,
                     normalize_kernel=normalize_kernel, preserve_nan=preserve_nan)

    assert np.all(np.array(array, dtype=dtype) == x)
    assert np.all(np.array(kernel, dtype=dtype) == y)
Beispiel #54
0
    def test_uniform_smallkernel(self, shape, width):
        """
        Test smoothing of an image with a single positive pixel

        Uses a simple, small kernel
        """

        if width % 2 == 0:
            # convolve does not accept odd-shape kernels
            return

        kernel = np.ones([width, width])

        x = np.zeros(shape)
        xslice = tuple([slice(sh // 2, sh // 2 + 1) for sh in shape])
        x[xslice] = 1.0

        c2 = convolve_fft(x, kernel, boundary='fill')
        c1 = convolve(x, kernel, boundary='fill')

        assert_almost_equal(c1, c2, decimal=12)
Beispiel #55
0
    def test_uniform_3_withnan(self, boundary, nan_treatment,
                               normalize_kernel, preserve_nan):
        '''
        Test that the different modes are producing the correct results using
        a uniform kernel with three elements. This version includes a NaN
        value in the original array.
        '''

        x = np.array([1., np.nan, 3.], dtype='float64')

        y = np.array([1., 1., 1.], dtype='float64')

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 normalize_kernel=normalize_kernel,
                                 preserve_nan=preserve_nan)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             normalize_kernel=normalize_kernel,
                             preserve_nan=preserve_nan)

        if preserve_nan:
            assert np.isnan(z[1])

        answer_dict = {
            'sum': np.array([1., 4., 3.], dtype='float64'),
            'sum_nozeros': np.array([1., 4., 3.], dtype='float64'),
            'sum_zeros': np.array([1., 4., 3.], dtype='float64'),
            'sum_nozeros_interpnan': np.array([1., 4., 3.], dtype='float64'),
            'average': np.array([1., 2., 3.], dtype='float64'),
            'sum_wrap': np.array([4., 4., 4.], dtype='float64'),
            'average_wrap': np.array([4/3., 4/3., 4/3.], dtype='float64'),
            'average_wrap_interpnan': np.array([2, 2, 2], dtype='float64'),
            'average_nozeros': np.array([1/2., 4/3., 3/2.], dtype='float64'),
            'average_nozeros_interpnan': np.array([1., 2., 3.], dtype='float64'),
            'average_zeros': np.array([1 / 3., 4 / 3., 3 / 3.], dtype='float64'),
            'average_zeros_interpnan': np.array([1 / 2., 4 / 2., 3 / 2.], dtype='float64'),
        }

        for key in list(answer_dict.keys()):
            if 'sum' in key:
                answer_dict[key+"_interpnan"] = answer_dict[key] * 3./2.

        if normalize_kernel:
            answer_key = 'average'
        else:
            answer_key = 'sum'

        if boundary == 'wrap':
            answer_key += '_wrap'
        else:
            # average = average_zeros; sum = sum_zeros
            answer_key += '_zeros'

        if nan_treatment == 'interpolate':
            answer_key += '_interpnan'

        posns = np.where(np.isfinite(z))

        assert_floatclose(z[posns], answer_dict[answer_key][posns])
Beispiel #56
0
    test_kernel = Gaussian2DKernel(1)

    result = convolve(ndd, test_kernel)

    x, y = np.mgrid[:11, :11]
    expected = result[5, 5] * np.exp(-0.5 * ((x - 5)**2 + (y - 5)**2))

    np.testing.assert_allclose(result, expected, atol=1e-6)

    resultf = convolve_fft(ndd, test_kernel)
    np.testing.assert_allclose(resultf, expected, atol=1e-6)


@pytest.mark.parametrize('convfunc',
   [lambda *args: convolve(*args, nan_treatment='interpolate', normalize_kernel=True),
    lambda *args: convolve_fft(*args, nan_treatment='interpolate', normalize_kernel=True)])
def test_masked_nddata(convfunc):
    arr = np.zeros((11, 11))
    arr[4, 5] = arr[6, 5] = arr[5, 4] = arr[5, 6] = 0.2
    arr[5, 5] = 1.5
    ndd_base = NDData(arr)

    mask = arr < 0  # this is all False
    mask[5, 5] = True
    ndd_mask = NDData(arr, mask=mask)

    arrnan = arr.copy()
    arrnan[5, 5] = np.nan
    ndd_nan = NDData(arrnan)

    test_kernel = Gaussian2DKernel(1)
Beispiel #57
0
    def test_uniform_3x3_withnan(self, boundary, nan_treatment,
                                 normalize_kernel, preserve_nan):
        '''
        Test that the different modes are producing the correct results using
        a 3x3 uniform kernel. This version includes a NaN value in the
        original array.
        '''

        x = np.array([[0., 0., 3.],
                      [1., np.nan, 0.],
                      [0., 2., 0.]], dtype='float64')

        y = np.array([[1., 1., 1.],
                      [1., 1., 1.],
                      [1., 1., 1.]], dtype='float64')

        # commented out: allow unnormalized nan-ignoring convolution
        # # kernel is not normalized, so this situation -> exception
        # if nan_treatment and not normalize_kernel:
        #     with pytest.raises(ValueError):
        #         z = convolve_fft(x, y, boundary=boundary,
        #                          nan_treatment=nan_treatment,
        #                          normalize_kernel=normalize_kernel,
        #                          ignore_edge_zeros=ignore_edge_zeros,
        #                          )
        #     return

        if boundary is None:
            with pytest.warns(AstropyUserWarning, match="The convolve_fft "
                              "version of boundary=None is equivalent to the "
                              "convolve boundary='fill'"):
                z = convolve_fft(x, y, boundary=boundary,
                                 nan_treatment=nan_treatment,
                                 fill_value=np.nan if normalize_kernel else 0,
                                 normalize_kernel=normalize_kernel,
                                 preserve_nan=preserve_nan)
        else:
            z = convolve_fft(x, y, boundary=boundary,
                             nan_treatment=nan_treatment,
                             fill_value=np.nan if normalize_kernel else 0,
                             normalize_kernel=normalize_kernel,
                             preserve_nan=preserve_nan)

        if preserve_nan:
            assert np.isnan(z[1, 1])

        # weights
        w_n = np.array([[3., 5., 3.],
                        [5., 8., 5.],
                        [3., 5., 3.]], dtype='float64')
        w_z = np.array([[4., 6., 4.],
                        [6., 9., 6.],
                        [4., 6., 4.]], dtype='float64')
        answer_dict = {
            'sum': np.array([[1., 4., 3.],
                             [3., 6., 5.],
                             [3., 3., 2.]], dtype='float64'),
            'sum_wrap': np.array([[6., 6., 6.],
                                  [6., 6., 6.],
                                  [6., 6., 6.]], dtype='float64'),
        }
        answer_dict['average'] = answer_dict['sum'] / w_z
        answer_dict['average_interpnan'] = answer_dict['sum'] / w_n
        answer_dict['average_wrap_interpnan'] = answer_dict['sum_wrap'] / 8.
        answer_dict['average_wrap'] = answer_dict['sum_wrap'] / 9.
        answer_dict['average_withzeros'] = answer_dict['sum'] / 9.
        answer_dict['average_withzeros_interpnan'] = answer_dict['sum'] / 8.
        answer_dict['sum_withzeros'] = answer_dict['sum']
        answer_dict['sum_interpnan'] = answer_dict['sum'] * 9/8.
        answer_dict['sum_withzeros_interpnan'] = answer_dict['sum']
        answer_dict['sum_wrap_interpnan'] = answer_dict['sum_wrap'] * 9/8.

        if normalize_kernel:
            answer_key = 'average'
        else:
            answer_key = 'sum'

        if boundary == 'wrap':
            answer_key += '_wrap'
        elif nan_treatment == 'fill':
            answer_key += '_withzeros'

        if nan_treatment == 'interpolate':
            answer_key += '_interpnan'

        answer_dict[answer_key]

        # Skip the NaN at [1, 1] when preserve_nan=True
        posns = np.where(np.isfinite(z))

        # for reasons unknown, the Windows FFT returns an answer for the [0, 0]
        # component that is EXACTLY 10*np.spacing
        assert_floatclose(z[posns], z[posns])