diff --git a/test_autoarray/structures/arrays/test_uniform_1d.py b/test_autoarray/structures/arrays/test_uniform_1d.py index 0c8576864..86fb636c9 100644 --- a/test_autoarray/structures/arrays/test_uniform_1d.py +++ b/test_autoarray/structures/arrays/test_uniform_1d.py @@ -2,6 +2,7 @@ from os import path import os import numpy as np +import pytest import shutil import autoarray as aa @@ -39,7 +40,7 @@ def clean_fits(fits_path): shutil.rmtree(fits_path) -def test__constructor(): +def test__constructor__with_partial_mask__masked_pixels_set_to_zero_in_native(): mask = aa.Mask1D( mask=[True, False, False, True, False, False], pixel_scales=1.0, @@ -55,7 +56,7 @@ def test__constructor(): assert array_1d.origin == (0.0,) -def test__no_mask(): +def test__no_mask__4_element_array__native_slim_and_grid_radial_correct(): array_1d = aa.Array1D.no_mask(values=[1.0, 2.0, 3.0, 4.0], pixel_scales=1.0) assert type(array_1d) == aa.Array1D @@ -67,7 +68,7 @@ def test__no_mask(): assert array_1d.origin == (0.0,) -def test__full(): +def test__full__fill_value_1_shape_4__all_elements_equal_fill_value(): array_1d = aa.Array1D.full( fill_value=1.0, shape_native=4, pixel_scales=1.0, origin=(4.0,) ) @@ -80,7 +81,7 @@ def test__full(): assert array_1d.origin == (4.0,) -def test__ones(): +def test__ones__shape_3_pixel_scale_3__all_native_elements_are_one(): array_1d = aa.Array1D.ones(shape_native=3, pixel_scales=3.0, origin=(4.0,)) assert type(array_1d) == aa.Array1D @@ -91,7 +92,7 @@ def test__ones(): assert array_1d.origin == (4.0,) -def test__zeros(): +def test__zeros__shape_3_pixel_scale_3__all_native_elements_are_zero(): array_1d = aa.Array1D.zeros(shape_native=3, pixel_scales=3.0, origin=(4.0,)) assert type(array_1d) == aa.Array1D @@ -102,7 +103,7 @@ def test__zeros(): assert array_1d.origin == (4.0,) -def test__from_fits(): +def test__from_fits__3_element_fits__native_and_slim_are_ones(): create_fits(fits_path=fits_path) arr = aa.Array1D.from_fits( @@ -113,6 +114,12 @@ def test__from_fits(): assert (arr.native == np.ones((3,))).all() assert (arr.slim == np.ones(3)).all() + clean_fits(fits_path=fits_path) + + +def test__from_fits__4_element_fits__native_slim_and_array_are_ones(): + create_fits(fits_path=fits_path) + arr = aa.Array1D.from_fits( file_path=path.join(fits_path, "4_ones.fits"), hdu=0, pixel_scales=1.0 ) @@ -125,7 +132,7 @@ def test__from_fits(): clean_fits(fits_path=fits_path) -def test__from_fits__loads_and_stores_header_info(): +def test__from_fits__3_element_fits__header_bitpix_is_minus_64(): create_fits(fits_path=fits_path) arr = aa.Array1D.from_fits( @@ -135,6 +142,12 @@ def test__from_fits__loads_and_stores_header_info(): assert arr.header.header_sci_obj["BITPIX"] == -64 assert arr.header.header_hdu_obj["BITPIX"] == -64 + clean_fits(fits_path=fits_path) + + +def test__from_fits__4_element_fits__header_bitpix_is_minus_64(): + create_fits(fits_path=fits_path) + arr = aa.Array1D.from_fits( file_path=path.join(fits_path, "4_ones.fits"), hdu=0, pixel_scales=1.0 ) @@ -145,7 +158,7 @@ def test__from_fits__loads_and_stores_header_info(): clean_fits(fits_path=fits_path) -def test__output_to_fits(): +def test__output_to_fits__ones_array__fits_file_has_correct_values_and_header(): arr = aa.Array1D.ones(shape_native=(3,), pixel_scales=1.0) if path.exists(test_data_path): @@ -169,12 +182,14 @@ def test__output_to_fits(): assert header_load["ORIGIN"] == 0.0 -def test__recursive_shape_storage(): +def test__recursive_shape_storage__no_mask__native_slim_native_roundtrip_correct(): array_1d = aa.Array1D.no_mask(values=[1.0, 2.0, 3.0, 4.0], pixel_scales=1.0) assert (array_1d.native.slim.native == np.array([1.0, 2.0, 3.0, 4.0])).all() assert (array_1d.slim.native.slim == np.array([1.0, 2.0, 3.0, 4.0])).all() + +def test__recursive_shape_storage__with_partial_mask__native_slim_native_roundtrip_correct(): mask = aa.Mask1D( mask=[True, False, False, True, False, False], pixel_scales=1.0, diff --git a/test_autoarray/structures/arrays/test_uniform_2d.py b/test_autoarray/structures/arrays/test_uniform_2d.py index 0c55b0c38..b306bbbeb 100644 --- a/test_autoarray/structures/arrays/test_uniform_2d.py +++ b/test_autoarray/structures/arrays/test_uniform_2d.py @@ -13,7 +13,7 @@ ) -def test__constructor(): +def test__constructor__2x2_all_false_mask__native_matches_input_2d_values(): mask = aa.Mask2D.all_false(shape_native=(2, 2), pixel_scales=1.0) array_2d = aa.Array2D(values=[[1.0, 2.0], [3.0, 4.0]], mask=mask) @@ -23,6 +23,8 @@ def test__constructor(): assert array_2d.pixel_scales == (1.0, 1.0) assert array_2d.origin == (0.0, 0.0) + +def test__constructor__partial_mask_with_1d_values__masked_pixels_zero_in_native(): mask = aa.Mask2D( mask=[[False, False], [True, False]], pixel_scales=1.0, origin=(0.0, 1.0) ) @@ -34,6 +36,8 @@ def test__constructor(): assert array_2d.pixel_scales == (1.0, 1.0) assert array_2d.origin == (0.0, 1.0) + +def test__constructor__partial_mask_with_2d_values__applies_mask_to_native(): mask = aa.Mask2D( mask=[[False, False], [True, False]], pixel_scales=1.0, origin=(0.0, 1.0) ) @@ -45,6 +49,8 @@ def test__constructor(): assert array_2d.pixel_scales == (1.0, 1.0) assert array_2d.origin == (0.0, 1.0) + +def test__constructor__store_native_true__stores_native_shape_including_masked_pixels(): mask = aa.Mask2D( mask=[[False, False], [True, False]], pixel_scales=1.0, @@ -55,7 +61,7 @@ def test__constructor(): assert (array_2d == np.array([[1.0, 2.0], [0.0, 4.0]])).all() -def test__no_mask(): +def test__no_mask__2x2_array__native_slim_and_pixel_scales_correct(): array_2d = aa.Array2D.no_mask( values=[[1.0, 2.0], [3.0, 4.0]], pixel_scales=1.0, @@ -68,23 +74,8 @@ def test__no_mask(): assert array_2d.pixel_scales == (1.0, 1.0) assert array_2d.origin == (0.0, 0.0) - array_2d = aa.Array2D.no_mask( - values=np.ones((9,)), - shape_native=(3, 3), - pixel_scales=(2.0, 1.0), - origin=(-1.0, -2.0), - ) - - assert array_2d == pytest.approx(np.ones((9,)), 1e-4) - assert array_2d.slim == pytest.approx(np.ones((9,)), 1e-4) - assert array_2d.native == pytest.approx(np.ones((3, 3)), 1e-4) - assert array_2d.pixel_scales == (2.0, 1.0) - assert array_2d.geometry.central_pixel_coordinates == (1.0, 1.0) - assert array_2d.geometry.shape_native_scaled == pytest.approx((6.0, 3.0)) - assert array_2d.origin == (-1.0, -2.0) - assert array_2d.geometry.scaled_maxima == pytest.approx((2.0, -0.5), 1e-4) - assert array_2d.geometry.scaled_minima == pytest.approx((-4.0, -3.5), 1e-4) +def test__no_mask__3x3_with_origin_and_anisotropic_scales__geometry_extents_correct(): array_2d = aa.Array2D.no_mask( values=np.ones((9,)), shape_native=(3, 3), @@ -103,7 +94,7 @@ def test__no_mask(): assert array_2d.geometry.scaled_minima == pytest.approx((-4.0, -3.5), 1e-4) -def test__apply_mask(): +def test__apply_mask__4x2_array_with_partial_mask__masked_rows_zero_in_native(): mask = aa.Mask2D( mask=[[False, False], [False, False], [True, True], [True, True]], pixel_scales=2.0, @@ -120,7 +111,7 @@ def test__apply_mask(): ).all() -def test__full(): +def test__full__fill_value_2_shape_2x2_with_origin__all_elements_equal_fill_value(): array_2d = aa.Array2D.full( fill_value=2.0, shape_native=(2, 2), pixel_scales=1.0, origin=(0.0, 1.0) ) @@ -132,7 +123,7 @@ def test__full(): assert array_2d.origin == (0.0, 1.0) -def test__ones(): +def test__ones__2x2_shape__all_native_elements_are_one(): array_2d = aa.Array2D.ones(shape_native=(2, 2), pixel_scales=1.0) assert type(array_2d) == aa.Array2D @@ -142,7 +133,7 @@ def test__ones(): assert array_2d.origin == (0.0, 0.0) -def test__zeros(): +def test__zeros__2x2_shape__all_native_elements_are_zero(): array_2d = aa.Array2D.zeros(shape_native=(2, 2), pixel_scales=1.0) assert type(array_2d) == aa.Array2D @@ -150,7 +141,7 @@ def test__zeros(): assert (array_2d.slim == np.array([0.0, 0.0, 0.0, 0.0])).all() -def test__from_fits(): +def test__from_fits__4x3_ones_fits__native_is_ones_array(): array_2d = aa.Array2D.from_fits( file_path=path.join(test_data_path, "4x3_ones.fits"), hdu=0, pixel_scales=1.0 ) @@ -160,7 +151,7 @@ def test__from_fits(): assert (array_2d.slim == np.ones((12,))).all() -def test__from_fits__loads_and_stores_header_info(): +def test__from_fits__3x3_fits__header_bitpix_stored_correctly(): array_2d = aa.Array2D.from_fits( file_path=path.join(test_data_path, "3x3_ones.fits"), hdu=0, pixel_scales=1.0 ) @@ -168,6 +159,8 @@ def test__from_fits__loads_and_stores_header_info(): assert array_2d.header.header_sci_obj["BITPIX"] == -64 assert array_2d.header.header_hdu_obj["BITPIX"] == -64 + +def test__from_fits__4x3_fits__header_bitpix_stored_correctly(): array_2d = aa.Array2D.from_fits( file_path=path.join(test_data_path, "4x3_ones.fits"), hdu=0, pixel_scales=1.0 ) @@ -176,7 +169,7 @@ def test__from_fits__loads_and_stores_header_info(): assert array_2d.header.header_hdu_obj["BITPIX"] == -64 -def test__from_yx_and_values(): +def test__from_yx_and_values__2x2_grid__native_matches_expected_pixel_layout(): array_2d = aa.Array2D.from_yx_and_values( y=[0.5, 0.5, -0.5, -0.5], x=[-0.5, 0.5, -0.5, 0.5], @@ -187,6 +180,8 @@ def test__from_yx_and_values(): assert (array_2d.native == np.array([[1.0, 2.0], [3.0, 4.0]])).all() + +def test__from_yx_and_values__3x2_grid__native_matches_expected_pixel_layout(): array_2d = aa.Array2D.from_yx_and_values( y=[0.0, 1.0, -1.0, 0.0, -1.0, 1.0], x=[-0.5, 0.5, 0.5, 0.5, -0.5, -0.5], @@ -198,7 +193,7 @@ def test__from_yx_and_values(): assert (array_2d.native == np.array([[3.0, 2.0], [6.0, 4.0], [5.0, 1.0]])).all() -def test__output_to_fits(): +def test__output_to_fits__3x3_ones__fits_file_has_ones_and_correct_pixel_scale_header(): test_data_path = path.join( "{}".format(path.dirname(path.realpath(__file__))), "files" ) @@ -234,7 +229,7 @@ def test__manual_native__exception_raised_if_input_array_is_2d_and_not_shape_of_ aa.Array2D(values=[[1.0], [3.0]], mask=mask) -def test__manual_mask__exception_raised_if_input_array_is_1d_and_not_number_of_masked_pixels(): +def test__constructor__1d_values_too_many_for_mask__raises_array_exception(): with pytest.raises(aa.exc.ArrayException): mask = aa.Mask2D( mask=[[False, False], [True, False]], @@ -242,6 +237,8 @@ def test__manual_mask__exception_raised_if_input_array_is_1d_and_not_number_of_m ) aa.Array2D(values=[1.0, 2.0, 3.0, 4.0], mask=mask) + +def test__constructor__1d_values_too_few_for_mask__raises_array_exception(): with pytest.raises(aa.exc.ArrayException): mask = aa.Mask2D( mask=[[False, False], [True, False]], @@ -250,64 +247,58 @@ def test__manual_mask__exception_raised_if_input_array_is_1d_and_not_number_of_m aa.Array2D(values=[1.0, 2.0], mask=mask) -def test__resized_from(): +@pytest.mark.parametrize("new_shape,expected_native", [ + ( + (7, 7), + np.array( + [ + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0], + [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0], + [0.0, 1.0, 1.0, 2.0, 1.0, 1.0, 0.0], + [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0], + [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + ] + ), + ), + ( + (3, 3), + np.array([[1.0, 1.0, 1.0], [1.0, 2.0, 1.0], [1.0, 1.0, 1.0]]), + ), +]) +def test__resized_from__5x5_array_with_center_marked__resized_array_pads_or_crops_correctly(new_shape, expected_native): array_2d = np.ones((5, 5)) array_2d[2, 2] = 2.0 array_2d = aa.Array2D.no_mask(values=array_2d, pixel_scales=(1.0, 1.0)) - array_2d = array_2d.resized_from(new_shape=(7, 7)) - - arr_resized_manual = np.array( - [ - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0], - [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0], - [0.0, 1.0, 1.0, 2.0, 1.0, 1.0, 0.0], - [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0], - [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - ] - ) + array_2d = array_2d.resized_from(new_shape=new_shape) assert type(array_2d) == aa.Array2D - assert (array_2d.native == arr_resized_manual).all() + assert (array_2d.native == expected_native).all() assert array_2d.mask.pixel_scales == (1.0, 1.0) - array_2d = np.ones((5, 5)) - array_2d[2, 2] = 2.0 - array_2d = aa.Array2D.no_mask(values=array_2d, pixel_scales=(1.0, 1.0)) - - array_2d = array_2d.resized_from(new_shape=(3, 3)) - - arr_resized_manual = np.array([[1.0, 1.0, 1.0], [1.0, 2.0, 1.0], [1.0, 1.0, 1.0]]) - - assert type(array_2d) == aa.Array2D - assert (array_2d.native == arr_resized_manual).all() - assert array_2d.mask.pixel_scales == (1.0, 1.0) - - -def test__padded_before_convolution_from(): +@pytest.mark.parametrize("kernel_shape,expected_shape", [ + ((3, 3), (7, 7)), + ((5, 5), (9, 9)), +]) +def test__padded_before_convolution_from__5x5_array__output_shape_padded_by_kernel_size(kernel_shape, expected_shape): array_2d = np.ones((5, 5)) array_2d[2, 2] = 2.0 array_2d = aa.Array2D.no_mask(values=array_2d, pixel_scales=(1.0, 1.0)) - new_arr = array_2d.padded_before_convolution_from(kernel_shape=(3, 3)) + new_arr = array_2d.padded_before_convolution_from(kernel_shape=kernel_shape) assert type(new_arr) == aa.Array2D assert new_arr.native[0, 0] == 0.0 - assert new_arr.shape_native == (7, 7) + assert new_arr.shape_native == expected_shape assert new_arr.mask.pixel_scales == (1.0, 1.0) - new_arr = array_2d.padded_before_convolution_from(kernel_shape=(5, 5)) - - assert type(new_arr) == aa.Array2D - assert new_arr.native[0, 0] == 0.0 - assert new_arr.shape_native == (9, 9) - assert new_arr.mask.pixel_scales == (1.0, 1.0) +def test__padded_before_convolution_from__9x9_array__output_shape_padded_by_7x7_kernel(): array_2d = np.ones((9, 9)) array_2d[4, 4] = 2.0 @@ -321,26 +312,24 @@ def test__padded_before_convolution_from(): assert new_arr.mask.pixel_scales == (1.0, 1.0) -def test__trimmed_after_convolution_from(): +@pytest.mark.parametrize("kernel_shape,expected_native", [ + ((3, 3), np.array([[1.0, 1.0, 1.0], [1.0, 2.0, 1.0], [1.0, 1.0, 1.0]])), + ((5, 5), np.array([[2.0]])), +]) +def test__trimmed_after_convolution_from__5x5_array_with_center_marked__trims_to_non_padded_region(kernel_shape, expected_native): array_2d = np.ones((5, 5)) array_2d[2, 2] = 2.0 array_2d = aa.Array2D.no_mask(values=array_2d, pixel_scales=(1.0, 1.0)) - new_arr = array_2d.trimmed_after_convolution_from(kernel_shape=(3, 3)) + new_arr = array_2d.trimmed_after_convolution_from(kernel_shape=kernel_shape) assert type(new_arr) == aa.Array2D - assert ( - new_arr.native == np.array([[1.0, 1.0, 1.0], [1.0, 2.0, 1.0], [1.0, 1.0, 1.0]]) - ).all() + assert (new_arr.native == expected_native).all() assert new_arr.mask.pixel_scales == (1.0, 1.0) - new_arr = array_2d.trimmed_after_convolution_from(kernel_shape=(5, 5)) - - assert type(new_arr) == aa.Array2D - assert (new_arr.native == np.array([[2.0]])).all() - assert new_arr.mask.pixel_scales == (1.0, 1.0) +def test__trimmed_after_convolution_from__9x9_array_with_center_marked__trims_to_non_padded_region(): array_2d = np.ones((9, 9)) array_2d[4, 4] = 2.0 @@ -355,15 +344,19 @@ def test__trimmed_after_convolution_from(): assert new_arr.mask.pixel_scales == (1.0, 1.0) -def test__binned_across_rows(): +def test__binned_across_rows__4x3_ones_array__each_column_bin_is_one(): array = aa.Array2D.no_mask(values=np.ones((4, 3)), pixel_scales=1.0) assert (array.binned_across_rows == np.array([1.0, 1.0, 1.0])).all() + +def test__binned_across_rows__3x4_ones_array__each_column_bin_is_one(): array = aa.Array2D.no_mask(values=np.ones((3, 4)), pixel_scales=1.0) assert (array.binned_across_rows == np.array([1.0, 1.0, 1.0, 1.0])).all() + +def test__binned_across_rows__3x3_non_uniform_values__columns_averaged_correctly(): array = aa.Array2D.no_mask( values=np.array([[1.0, 6.0, 9.0], [2.0, 6.0, 9.0], [3.0, 6.0, 9.0]]), pixel_scales=1.0, @@ -371,6 +364,8 @@ def test__binned_across_rows(): assert (array.binned_across_rows == np.array([2.0, 6.0, 9.0])).all() + +def test__binned_across_rows__3x3_with_partial_mask__masked_pixels_excluded_from_average(): mask = aa.Mask2D( mask=[[False, False, False], [False, False, False], [True, False, False]], pixel_scales=1.0, @@ -384,15 +379,19 @@ def test__binned_across_rows(): assert (array.binned_across_rows == np.array([1.5, 6.0, 9.0])).all() -def test__binned_across_columns(): +def test__binned_across_columns__4x3_ones_array__each_row_bin_is_one(): array = aa.Array2D.no_mask(values=np.ones((4, 3)), pixel_scales=1.0) assert (array.binned_across_columns == np.array([1.0, 1.0, 1.0, 1.0])).all() + +def test__binned_across_columns__3x4_ones_array__each_row_bin_is_one(): array = aa.Array2D.no_mask(values=np.ones((3, 4)), pixel_scales=1.0) assert (array.binned_across_columns == np.array([1.0, 1.0, 1.0])).all() + +def test__binned_across_columns__3x3_non_uniform_values__rows_averaged_correctly(): array = aa.Array2D.no_mask( values=np.array([[1.0, 2.0, 3.0], [6.0, 6.0, 6.0], [9.0, 9.0, 9.0]]), pixel_scales=1.0, @@ -400,6 +399,8 @@ def test__binned_across_columns(): assert (array.binned_across_columns == np.array([2.0, 6.0, 9.0])).all() + +def test__binned_across_columns__3x3_with_partial_mask__masked_pixels_excluded_from_average(): mask = aa.Mask2D( mask=[[False, False, True], [False, False, False], [False, False, False]], pixel_scales=1.0, @@ -413,7 +414,7 @@ def test__binned_across_columns(): assert (array.binned_across_columns == np.array([1.5, 6.0, 9.0])).all() -def test__brightest_pixel_in_region_from(): +def test__brightest_coordinate_in_region_from__4x4_array__correct_peak_coordinate(): mask = aa.Mask2D.all_false(shape_native=(4, 4), pixel_scales=0.1) array_2d = aa.Array2D( values=[ @@ -431,12 +432,27 @@ def test__brightest_pixel_in_region_from(): assert brightest_coordinate == pytest.approx((-0.15, 0.05), 1.0e-4) + +def test__brightest_coordinate_in_region_from__4x4_array_different_region__correct_peak_coordinate(): + mask = aa.Mask2D.all_false(shape_native=(4, 4), pixel_scales=0.1) + array_2d = aa.Array2D( + values=[ + [1.0, 2.0, 3.0, 4.0], + [6.0, 7.0, 8.0, 9.0], + [11.0, 12.0, 13.0, 15.0], + [16.0, 17.0, 18.0, 20.0], + ], + mask=mask, + ) + brightest_coordinate = array_2d.brightest_coordinate_in_region_from( region=(-0.051, 0.151, -0.151, 0.149) ) assert brightest_coordinate == pytest.approx((-0.05, 0.05), 1.0e-4) + +def test__brightest_coordinate_in_region_from__5x5_array__correct_peak_coordinate(): mask = aa.Mask2D.all_false(shape_native=(5, 5), pixel_scales=0.1) array_2d = aa.Array2D( values=[ @@ -455,6 +471,20 @@ def test__brightest_pixel_in_region_from(): assert brightest_coordinate == pytest.approx((-0.1, 0.1), 1.0e-4) + +def test__brightest_coordinate_in_region_from__5x5_array_asymmetric_region__correct_peak_coordinate(): + mask = aa.Mask2D.all_false(shape_native=(5, 5), pixel_scales=0.1) + array_2d = aa.Array2D( + values=[ + [1.0, 2.0, 3.0, 4.0, 5.0], + [6.0, 7.0, 8.0, 9.0, 10.0], + [11.0, 12.0, 13.0, 14.0, 15.0], + [16.0, 17.0, 18.0, 19.0, 20.0], + [21.0, 22.0, 23.0, 24.0, 25.0], + ], + mask=mask, + ) + brightest_coordinate = array_2d.brightest_coordinate_in_region_from( region=(-0.25, 0.15, -0.15, 0.15) ) @@ -468,7 +498,7 @@ def test__brightest_pixel_in_region_from(): assert brightest_coordinate == pytest.approx((-0.1, 0.2), 1.0e-4) -def test__brightest_sub_pixel_in_region_from(): +def test__brightest_sub_pixel_coordinate_in_region_from__4x4_array__correct_sub_pixel_peak(): mask = aa.Mask2D.all_false(shape_native=(4, 4), pixel_scales=0.1) array_2d = aa.Array2D( values=[ @@ -486,6 +516,8 @@ def test__brightest_sub_pixel_in_region_from(): assert brightest_coordinate == pytest.approx((-0.1078947, 0.056315), 1.0e-4) + +def test__brightest_sub_pixel_coordinate_in_region_from__5x5_array__correct_sub_pixel_peak(): mask = aa.Mask2D.all_false(shape_native=(5, 5), pixel_scales=0.1) array_2d = aa.Array2D( values=[ @@ -505,7 +537,7 @@ def test__brightest_sub_pixel_in_region_from(): assert brightest_coordinate == pytest.approx((-0.11754, 0.103508), 1.0e-4) -def test__header__modified_julian_date(): +def test__header__date_obs_and_time_obs__modified_julian_date_correct(): header_sci_obj = {"DATE-OBS": "2000-01-01", "TIME-OBS": "00:00:00"} header = aa.Header(header_sci_obj=header_sci_obj, header_hdu_obj=None) @@ -513,11 +545,19 @@ def test__header__modified_julian_date(): assert header.modified_julian_date == 51544.0 -def test__array_2d__recursive_shape_storage(): +def test__recursive_shape_storage__native_to_slim_to_native__roundtrip_correct(): array_2d = aa.Array2D.no_mask( values=[[1.0, 2.0], [3.0, 4.0]], pixel_scales=1.0, ) assert (array_2d.native.slim.native == np.array([[1.0, 2.0], [3.0, 4.0]])).all() + + +def test__recursive_shape_storage__slim_to_native_to_slim__roundtrip_correct(): + array_2d = aa.Array2D.no_mask( + values=[[1.0, 2.0], [3.0, 4.0]], + pixel_scales=1.0, + ) + assert (array_2d.slim.native.slim == np.array([1.0, 2.0, 3.0, 4.0])).all() diff --git a/test_autoarray/structures/grids/test_uniform_1d.py b/test_autoarray/structures/grids/test_uniform_1d.py index e641c4015..f6438ac57 100644 --- a/test_autoarray/structures/grids/test_uniform_1d.py +++ b/test_autoarray/structures/grids/test_uniform_1d.py @@ -5,7 +5,7 @@ import autoarray as aa -def test__constructor(): +def test__constructor__all_false_mask__native_slim_pixel_scales_origin_correct(): mask = aa.Mask1D.all_false(shape_slim=(4,), pixel_scales=1.0) grid = aa.Grid1D(values=[1.0, 2.0, 3.0, 4.0], mask=mask) @@ -15,6 +15,8 @@ def test__constructor(): assert grid.pixel_scales == (1.0,) assert grid.origin == (0.0,) + +def test__constructor__partial_mask__masked_pixel_zero_in_native_and_slim_roundtrip_correct(): mask = aa.Mask1D(mask=[True, False, False], pixel_scales=1.0) grid = aa.Grid1D(values=[1.0, 2.0, 3.0], mask=mask) @@ -28,7 +30,7 @@ def test__constructor(): assert (grid.native.slim == np.array([2.0, 3.0])).all() -def test__no_mask(): +def test__no_mask__4_element_grid__native_slim_pixel_scales_origin_correct(): grid_1d = aa.Grid1D.no_mask( values=[1.0, 2.0, 3.0, 4.0], pixel_scales=1.0, @@ -40,6 +42,8 @@ def test__no_mask(): assert grid_1d.pixel_scales == (1.0,) assert grid_1d.origin == (0.0,) + +def test__no_mask__4_element_grid_with_origin__origin_stored_and_accessible(): grid_1d = aa.Grid1D.no_mask( values=[1.0, 2.0, 3.0, 4.0], pixel_scales=1.0, origin=(1.0,) ) @@ -51,7 +55,7 @@ def test__no_mask(): assert grid_1d.origin == (1.0,) -def test__from_mask(): +def test__from_mask__all_false_4_element__native_coordinates_are_pixel_centers(): mask = aa.Mask1D.all_false(shape_slim=(4,), pixel_scales=1.0) grid = aa.Grid1D.from_mask(mask=mask) @@ -61,6 +65,8 @@ def test__from_mask(): assert grid.pixel_scales == (1.0,) assert grid.origin == (0.0,) + +def test__from_mask__partial_mask__masked_pixel_zero_in_native_slim_has_unmasked_coordinates(): mask = aa.Mask1D(mask=[True, False, False, False], pixel_scales=1.0) grid = aa.Grid1D.from_mask(mask=mask) @@ -71,7 +77,7 @@ def test__from_mask(): assert grid.origin == (0.0,) -def test__uniform(): +def test__uniform__2_element_pixel_scale_1_origin_0__native_at_half_pixel_centers(): grid_1d = aa.Grid1D.uniform(shape_native=(2,), pixel_scales=1.0, origin=(0.0,)) assert type(grid_1d) == aa.Grid1D @@ -80,6 +86,8 @@ def test__uniform(): assert grid_1d.pixel_scales == (1.0,) assert grid_1d.origin == (0.0,) + +def test__uniform__2_element_pixel_scale_1_origin_1__native_offset_by_origin(): grid_1d = aa.Grid1D.uniform(shape_native=(2,), pixel_scales=1.0, origin=(1.0,)) assert type(grid_1d) == aa.Grid1D @@ -89,7 +97,7 @@ def test__uniform(): assert grid_1d.origin == (1.0,) -def test__uniform_from_zero(): +def test__uniform_from_zero__2_element_pixel_scale_1__starts_at_zero(): grid_1d = aa.Grid1D.uniform_from_zero( shape_native=(2,), pixel_scales=1.0, @@ -101,6 +109,8 @@ def test__uniform_from_zero(): assert grid_1d.pixel_scales == (1.0,) assert grid_1d.origin == (0.0,) + +def test__uniform_from_zero__3_element_pixel_scale_1p5__starts_at_zero_with_correct_spacing(): grid_1d = aa.Grid1D.uniform_from_zero( shape_native=(3,), pixel_scales=1.5, @@ -113,7 +123,7 @@ def test__uniform_from_zero(): assert grid_1d.origin == (0.0,) -def test__grid_2d_radial_projected_from(): +def test__grid_2d_radial_projected_from__angle_0__projects_along_x_axis(): grid_1d = aa.Grid1D.no_mask( values=[1.0, 2.0, 3.0, 4.0], pixel_scales=1.0, @@ -126,12 +136,26 @@ def test__grid_2d_radial_projected_from(): np.array([[0.0, 1.0], [0.0, 2.0], [0.0, 3.0], [0.0, 4.0]]), abs=1.0e-4 ) + +def test__grid_2d_radial_projected_from__angle_90__projects_along_negative_y_axis(): + grid_1d = aa.Grid1D.no_mask( + values=[1.0, 2.0, 3.0, 4.0], + pixel_scales=1.0, + ) + grid_2d = grid_1d.grid_2d_radial_projected_from(angle=90.0) assert grid_2d.slim == pytest.approx( np.array([[-1.0, 0.0], [-2.0, 0.0], [-3.0, 0.0], [-4.0, 0.0]]), abs=1.0e-4 ) + +def test__grid_2d_radial_projected_from__angle_45__projects_along_diagonal(): + grid_1d = aa.Grid1D.no_mask( + values=[1.0, 2.0, 3.0, 4.0], + pixel_scales=1.0, + ) + grid_2d = grid_1d.grid_2d_radial_projected_from(angle=45.0) assert grid_2d.slim == pytest.approx( @@ -147,13 +171,15 @@ def test__grid_2d_radial_projected_from(): ) -def test__recursive_shape_storage(): +def test__recursive_shape_storage__no_mask__slim_native_slim_roundtrip_correct(): mask = aa.Mask1D.all_false(shape_slim=(4,), pixel_scales=1.0) grid = aa.Grid1D(values=[1.0, 2.0, 3.0, 4.0], mask=mask) assert (grid.slim.native.slim == np.array([1.0, 2.0, 3.0, 4.0])).all() assert (grid.native.slim.native == np.array([1.0, 2.0, 3.0, 4.0])).all() + +def test__recursive_shape_storage__partial_mask__slim_native_slim_roundtrip_correct(): mask = aa.Mask1D(mask=[True, False, False], pixel_scales=1.0) grid = aa.Grid1D(values=[1.0, 2.0, 3.0], mask=mask) diff --git a/test_autoarray/structures/grids/test_uniform_2d.py b/test_autoarray/structures/grids/test_uniform_2d.py index 9352dfbb1..cebaeeff3 100644 --- a/test_autoarray/structures/grids/test_uniform_2d.py +++ b/test_autoarray/structures/grids/test_uniform_2d.py @@ -9,7 +9,7 @@ test_grid_dir = path.join("{}".format(path.dirname(path.realpath(__file__))), "files") -def test__constructor(): +def test__constructor__2x2_all_false_mask__native_slim_and_pixel_scales_correct(): mask = aa.Mask2D.all_false(shape_native=(2, 2), pixel_scales=1.0) grid_2d = aa.Grid2D( values=[[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]], mask=mask @@ -32,17 +32,19 @@ def test__constructor__exception_raised_if_input_grid_is_2d_and_not_shape_of_mas aa.Grid2D(values=[[[1.0, 1.0], [3.0, 3.0]]], mask=mask) -def test__constructor__exception_raised_if_input_grid_is_not_number_of_masked_pixels(): +def test__constructor__1d_values_too_many_for_masked_pixels__raises_grid_exception(): with pytest.raises(exc.GridException): mask = aa.Mask2D(mask=[[False, False], [True, False]], pixel_scales=1.0) aa.Grid2D(values=[[1.0, 1.0], [2.0, 2.0], [3.0, 3.0], [4.0, 4.0]], mask=mask) + +def test__constructor__1d_values_too_few_for_masked_pixels__raises_grid_exception(): with pytest.raises(exc.GridException): mask = aa.Mask2D(mask=[[False, False], [True, False]], pixel_scales=1.0) aa.Grid2D(values=[[1.0, 1.0], [2.0, 2.0]], mask=mask) -def test__no_mask(): +def test__no_mask__2x2_native_values__native_slim_pixel_scales_and_origin_correct(): grid_2d = aa.Grid2D.no_mask( values=[[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]], pixel_scales=1.0, @@ -60,6 +62,8 @@ def test__no_mask(): assert grid_2d.pixel_scales == (1.0, 1.0) assert grid_2d.origin == (0.0, 0.0) + +def test__no_mask__with_origin__origin_stored_and_accessible(): grid_2d = aa.Grid2D.no_mask( values=[[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]], shape_native=(4, 2), @@ -79,7 +83,7 @@ def test__no_mask(): assert grid_2d.origin == (0.0, 1.0) -def test__from_yx_2d(): +def test__from_yx_2d__2x1_grid__correct_native_slim_and_pixel_scales(): grid_2d = aa.Grid2D.from_yx_2d( y=[[1.0], [3.0]], x=[[2.0], [4.0]], pixel_scales=(2.0, 3.0) ) @@ -157,7 +161,7 @@ def test__from_extent(): assert grid_2d.origin == (0.0, 0.0) -def test__uniform(): +def test__uniform__2x2_pixel_scale_2__native_coordinates_correct(): grid_2d = aa.Grid2D.uniform(shape_native=(2, 2), pixel_scales=2.0) assert type(grid_2d) == aa.Grid2D @@ -171,6 +175,8 @@ def test__uniform(): assert grid_2d.pixel_scales == (2.0, 2.0) assert grid_2d.origin == (0.0, 0.0) + +def test__uniform__2x2_with_origin__coordinates_offset_by_origin(): grid_2d = aa.Grid2D.uniform( shape_native=(2, 2), pixel_scales=2.0, origin=(1.0, 1.0) ) @@ -186,6 +192,8 @@ def test__uniform(): assert grid_2d.pixel_scales == (2.0, 2.0) assert grid_2d.origin == (1.0, 1.0) + +def test__uniform__4x2_non_square__all_native_coordinates_correct(): grid_2d = aa.Grid2D.uniform(shape_native=(4, 2), pixel_scales=0.5) assert type(grid_2d) == aa.Grid2D @@ -219,7 +227,7 @@ def test__uniform(): assert grid_2d.origin == (0.0, 0.0) -def test__bounding_box(): +def test__bounding_box__square_bounding_box_3x3__slim_coordinates_and_pixel_scales_correct(): grid_2d = aa.Grid2D.bounding_box( bounding_box=[-2.0, 2.0, -2.0, 2.0], shape_native=(3, 3), @@ -246,6 +254,8 @@ def test__bounding_box(): assert grid_2d.pixel_scales == pytest.approx((1.33333, 1.3333), 1.0e-4) assert grid_2d.origin == (0.0, 0.0) + +def test__bounding_box__rectangular_bounding_box_2x3__slim_coordinates_and_pixel_scales_correct(): grid_2d = aa.Grid2D.bounding_box( bounding_box=[-2.0, 2.0, -2.0, 2.0], shape_native=(2, 3), @@ -269,7 +279,7 @@ def test__bounding_box(): assert grid_2d.origin == (0.0, 0.0) -def test__bounding_box__buffer_around_corners(): +def test__bounding_box__buffer_around_corners_2x3__coordinates_at_exact_corners(): grid_2d = aa.Grid2D.bounding_box( bounding_box=[-2.0, 2.0, -2.0, 2.0], shape_native=(2, 3), @@ -292,6 +302,8 @@ def test__bounding_box__buffer_around_corners(): assert grid_2d.pixel_scales == (4.0, 2.0) assert grid_2d.origin == (0.0, 0.0) + +def test__bounding_box__buffer_around_corners_3x3_offset_box__coordinates_and_origin_correct(): grid_2d = aa.Grid2D.bounding_box( bounding_box=[8.0, 10.0, -2.0, 3.0], shape_native=(3, 3), @@ -334,7 +346,7 @@ def test__bounding_box__buffer_around_corners(): assert grid_2d.origin == (9.0, 0.5) -def test__grid_2d_via_deflection_grid_from(): +def test__grid_2d_via_deflection_grid_from__grid_deflected_by_itself__all_zero_coordinates(): grid_2d = aa.Grid2D.uniform(shape_native=(2, 2), pixel_scales=2.0) grid_deflected = grid_2d.grid_2d_via_deflection_grid_from(deflection_grid=grid_2d)