From bdc5c2d3e86b3b31ad457da3015ad888a71c7068 Mon Sep 17 00:00:00 2001 From: Kadri Nizam Date: Wed, 5 Apr 2023 16:05:45 -0400 Subject: [PATCH 1/6] GridCoords constructor with props and cached_props --- src/mpol/coordinates.py | 277 +++++++++++++++++++++++++++------------- 1 file changed, 189 insertions(+), 88 deletions(-) diff --git a/src/mpol/coordinates.py b/src/mpol/coordinates.py index c30bb6f0..64f1ef4d 100644 --- a/src/mpol/coordinates.py +++ b/src/mpol/coordinates.py @@ -1,15 +1,16 @@ from __future__ import annotations +from functools import cached_property from typing import Any import numpy as np import numpy.fft as np_fft -import numpy.typing as npt +from numpy import floating +from numpy.typing import NDArray, ArrayLike import mpol.constants as const from mpol.exceptions import CellSizeError - -from .utils import get_max_spatial_freq, get_maximum_cell_size +from mpol.utils import get_max_spatial_freq, get_maximum_cell_size class GridCoords: @@ -35,7 +36,7 @@ class GridCoords: :ivar packed_x_centers_2D: 2D array of l increasing, with fftshifted applied [arcseconds]. Useful for directly evaluating some function to create a packed cube. :ivar packed_y_centers_2D: 2D array of m increasing, with fftshifted applied [arcseconds]. Useful for directly evaluating some function to create a packed cube. :ivar sky_x_centers_2D: 2D array of l arranged for evaluating a sky image [arcseconds]. l coordinate increases to the left (as on sky). - :ivar sky_y_centers_2D: 2D array of m arranged for evaluating a sky image [arcseconds]. + :ivar sky_y_centers_2D: 2D array of m arranged for evaluating a sky image [arcseconds]. :ivar du: Fourier-plane cell spacing in East-West direction [:math:`\mathrm{k}\lambda`] :ivar dv: Fourier-plane cell spacing in North-South direction [:math:`\mathrm{k}\lambda`] :ivar u_centers: 1D array of cell centers in East-West direction [:math:`\mathrm{k}\lambda`]. @@ -50,109 +51,205 @@ class GridCoords: :ivar vis_ext: length-4 list of (left, right, bottom, top) expected by routines like ``matplotlib.pyplot.imshow`` in the ``extent`` parameter assuming ``origin='lower'``. Units of [:math:`\mathrm{k}\lambda`] """ - def __init__(self, cell_size: float, npix: int) -> None: - # set up the bin edges, centers, etc. - if not npix % 2 == 0: - raise ValueError("Image must have an even number of pixels.") + def __init__(self, cell_size: float, npix: int): + if npix <= 0 or not (npix % 2 == 0): + raise ValueError("Image must have a positive and even number of pixels.") if cell_size <= 0: raise ValueError("cell_size must be a positive real number.") - self.cell_size = cell_size # arcsec - self.npix = npix - self.ncell_u = self.npix - self.ncell_v = self.npix + # Imply to users that GridCoords instance is read-only and new instance + # is the approach if changing values + self._cell_size = cell_size + self._npix = npix - # calculate the image extent - # say we had 10 pixels representing centers -5, -4, -3, ... - # it should go from -5.5 to +4.5 - lmax = cell_size * (self.npix // 2 - 0.5) - lmin = -cell_size * (self.npix // 2 + 0.5) - self.img_ext = [lmax, lmin, lmin, lmax] # arcsecs + # Image related + self._dimage = self.cell_size * const.arcsec # [radians] + self._image_centers = self._dimage * np.arange(npix) - npix // 2 - self.dl = cell_size * const.arcsec # [radians] - self.dm = cell_size * const.arcsec # [radians] + # Frequency related + # These properties are identical for both u & v and defined here + self._df = 1 / (npix * self._dimage) * 1e-3 # [kλ] + self._f_edges = self._dimage * (np.arange(npix + 1) - npix // 2 - 0.5) # [kλ] + self._f_centers = self._df * (np.arange(npix) - npix // 2) + self._min_f = float(self._f_edges.min()) + self._max_f = float(self._f_edges.max()) - int_l_centers = np.arange(self.npix) - self.npix // 2 - int_m_centers = np.arange(self.npix) - self.npix // 2 - self.l_centers = self.dl * int_l_centers # [radians] - self.m_centers = self.dm * int_m_centers # [radians] + # max u or v freq supported by current grid + self.max_grid = get_max_spatial_freq(cell_size, npix) - # the output spatial frequencies of the FFT routine - self.du = 1 / (self.npix * self.dl) * 1e-3 # [kλ] - self.dv = 1 / (self.npix * self.dm) * 1e-3 # [kλ] + @property + def cell_size(self) -> float: + return self._cell_size - # define the max/min of the FFT grid - # because we store images as [y, x] - # this means we store visibilities as [v, u] - int_u_edges = np.arange(self.ncell_u + 1) - self.ncell_v // 2 - 0.5 - int_v_edges = np.arange(self.ncell_v + 1) - self.ncell_v // 2 - 0.5 + @property + def npix(self) -> int: + return self._npix - self.u_edges = self.du * int_u_edges # [kλ] - self.v_edges = self.dv * int_v_edges # [kλ] + @property + def dl(self) -> float: + return self._dimage # [radians] - int_u_centers = np.arange(self.ncell_u) - self.ncell_u // 2 - int_v_centers = np.arange(self.ncell_v) - self.ncell_v // 2 - self.u_centers = self.du * int_u_centers # [kλ] - self.v_centers = self.dv * int_v_centers # [kλ] + @property + def dm(self) -> float: + return self._dimage # [radians] - self.v_bin_min = np.min(self.v_edges) - self.v_bin_max = np.max(self.v_edges) + @property + def l_centers(self) -> NDArray[floating[Any]]: + return self._image_centers - self.u_bin_min = np.min(self.u_edges) - self.u_bin_max = np.max(self.u_edges) + @property + def m_centers(self) -> NDArray[floating[Any]]: + return self._image_centers - self.vis_ext = [ - self.u_bin_min, - self.u_bin_max, - self.v_bin_min, - self.v_bin_max, - ] # [kλ] + @property + def ncell_u(self) -> int: + return self.npix - # max u or v freq supported by current grid - self.max_grid = get_max_spatial_freq(self.cell_size, self.npix) + @property + def ncell_v(self) -> int: + return self.npix - # only useful for plotting a sky_vis... uu, vv increasing, no fftshift - self.sky_u_centers_2D, self.sky_v_centers_2D = np.meshgrid( - self.u_centers, self.v_centers, indexing="xy" - ) # cartesian indexing (default) + @property + def du(self) -> float: + return self._df - # only useful for plotting... uu, vv increasing, no fftshift - self.sky_q_centers_2D = np.sqrt( - self.sky_u_centers_2D**2 + self.sky_v_centers_2D**2 - ) # [kλ] + @property + def dv(self) -> float: + return self._df - # https://en.wikipedia.org/wiki/Atan2 - self.sky_phi_centers_2D = np.arctan2( - self.sky_v_centers_2D, self.sky_u_centers_2D - ) # (pi, pi] + @property + def u_edges(self) -> NDArray[floating[Any]]: + return self._f_edges - # for evaluating a packed vis... uu, vv increasing + fftshifted - self.packed_u_centers_2D = np_fft.fftshift(self.sky_u_centers_2D) - self.packed_v_centers_2D = np_fft.fftshift(self.sky_v_centers_2D) + @property + def v_edges(self) -> NDArray[floating[Any]]: + return self._f_edges - # and in polar coordinates too - self.packed_q_centers_2D = np_fft.fftshift(self.sky_q_centers_2D) - self.packed_phi_centers_2D = np_fft.fftshift(self.sky_phi_centers_2D) + @property + def u_centers(self) -> NDArray[floating[Any]]: + return self._f_centers - self.q_max = float( - np.max(np.abs(self.packed_q_centers_2D)) + np.sqrt(2) * self.du - ) # outer edge [klambda] + @property + def v_centers(self) -> NDArray[floating[Any]]: + return self._f_centers - # x_centers_2D and y_centers_2D are just l and m in units of arcsec - x_centers_2D, y_centers_2D = np.meshgrid( - self.l_centers / const.arcsec, self.m_centers / const.arcsec, indexing="xy" - ) # [arcsec] cartesian indexing (default) + @property + def u_bin_min(self) -> float: + return self._min_f - # for evaluating a packed cube... ll, mm increasing + fftshifted - self.packed_x_centers_2D = np_fft.fftshift(x_centers_2D) # [arcsec] - self.packed_y_centers_2D = np_fft.fftshift(y_centers_2D) # [arcsec] + @property + def v_bin_min(self) -> float: + return self._min_f - # for evaluating a sky image... ll mirrored, mm increasing, no fftshift - self.sky_y_centers_2D = y_centers_2D # [arcsec] - self.sky_x_centers_2D = np.fliplr(x_centers_2D) # [arcsec] + @property + def u_bin_max(self) -> float: + return self._max_f - def check_data_fit(self, uu: npt.ArrayLike, vv: npt.ArrayLike) -> None: + @property + def v_bin_max(self) -> float: + return self._max_f + + @property + def img_ext(self) -> list[float]: + # calculate the image extent + # say we had 10 pixels representing centers -5, -4, -3, ... + # it should go from -5.5 to +4.5 + lmax = self.cell_size * (self.npix // 2 - 0.5) + lmin = -self.cell_size * (self.npix // 2 + 0.5) + return [lmax, lmin, lmin, lmax] # arcsecs + + @property + def vis_ext(self) -> list[float]: + return [ + self.u_bin_min, + self.u_bin_max, + self.v_bin_min, + self.v_bin_max, + ] # [kλ] + + # -------------------------------------------------------------------------- + # Non-identical u & v properties + # -------------------------------------------------------------------------- + @cached_property + def sky_u_centers_2D(self) -> NDArray[floating[Any]]: + # only useful for plotting a sky_vis + # uu increasing, no fftshift + return np.tile(self.u_centers, (self.ncell_u, 1)) + + @cached_property + def sky_v_centers_2D(self) -> NDArray[floating[Any]]: + # only useful for plotting a sky_vis + # vv increasing, no fftshift + return np.tile(self.v_centers, (self.ncell_v, 1)).T + + @cached_property + def packed_u_centers_2D(self) -> NDArray[floating[Any]]: + # for evaluating a packed vis + # uu increasing, fftshifted + return np_fft.fftshift(self.sky_u_centers_2D) + + @cached_property + def packed_v_centers_2D(self) -> NDArray[floating[Any]]: + # for evaluating a packed vis + # vv increasing + fftshifted + return np_fft.fftshift(self.sky_v_centers_2D) + + @cached_property + def sky_q_centers_2D(self) -> NDArray[floating[Any]]: + return np.sqrt(self.sky_u_centers_2D**2 + self.sky_v_centers_2D**2) # [kλ] + + @cached_property + def sky_phi_centers_2D(self) -> NDArray[floating[Any]]: + # https://en.wikipedia.org/wiki/Atan2 + return np.arctan2(self.sky_v_centers_2D, self.sky_u_centers_2D) # (pi, pi] + + @cached_property + def packed_q_centers_2D(self) -> NDArray[floating[Any]]: + # for evaluating a packed vis in polar coordinates + # q increasing, fftshifted + return np_fft.fftshift(self.sky_q_centers_2D) + + @cached_property + def packed_phi_centers_2D(self) -> NDArray[floating[Any]]: + # for evaluating a packed vis in polar coordinates + # phi increasing, fftshifted + return np_fft.fftshift(self.sky_phi_centers_2D) + + @cached_property + def q_max(self) -> float: + # outer edge [klambda] + return float(np.abs(self.packed_q_centers_2D).max() + np.sqrt(2) * self.du) + + @cached_property + def x_centers_2D(self) -> NDArray[floating[Any]]: + return np.tile(self.l_centers / const.arcsec, (self.npix, 1)) # [arcsec] + + @cached_property + def y_centers_2D(self) -> NDArray[floating[Any]]: + return np.tile(self.m_centers / const.arcsec, (self.npix, 1)).T # [arcsec] + + @cached_property + def packed_x_centers_2D(self) -> NDArray[floating[Any]]: + return np.fft.fftshift(self.x_centers_2D) # [arcsec] + + @cached_property + def packed_y_centers_2D(self) -> NDArray[floating[Any]]: + return np.fft.fftshift(self.y_centers_2D) # [arcsec] + + @property + def sky_x_centers_2D(self) -> NDArray[floating[Any]]: + # for evaluating a sky image + # ll mirrored, increasing, no fftshift + return np.fliplr(self.x_centers_2D) # [arcsec] + + @property + def sky_y_centers_2D(self) -> NDArray[floating[Any]]: + # for evaluating a sky image + # mm increasing, no fftshift + return self.y_centers_2D # [arcsec] + + def check_data_fit(self, uu: ArrayLike, vv: ArrayLike) -> None: r""" Test whether loose data visibilities fit within the Fourier grid defined by cell_size and npix. @@ -165,19 +262,23 @@ def check_data_fit(self, uu: npt.ArrayLike, vv: npt.ArrayLike) -> None: """ # max freq in dataset - max_uu_vv = np.max(np.abs(np.concatenate([uu, vv]))) + max_uu_vv = np.abs(np.concatenate([uu, vv])).max() # max freq needed to support dataset max_cell_size = get_maximum_cell_size(max_uu_vv) - if np.max(np.abs(uu)) > self.max_grid: + if np.abs(uu).max() > self.max_grid: raise CellSizeError( - f"Dataset contains uu spatial frequency measurements larger than those in the proposed model image. Decrease cell_size below {max_cell_size} arcsec." + "Dataset contains uu spatial frequency measurements larger " + "than those in the proposed model image. " + f"Decrease cell_size below {max_cell_size} arcsec." ) - if np.max(np.abs(vv)) > self.max_grid: + if np.abs(vv).max() > self.max_grid: raise CellSizeError( - f"Dataset contains vv spatial frequency measurements larger than those in the proposed model image. Decrease cell_size below {max_cell_size} arcsec." + "Dataset contains vv spatial frequency measurements larger " + "than those in the proposed model image. " + f"Decrease cell_size below {max_cell_size} arcsec." ) def __eq__(self, other: Any) -> bool: @@ -187,4 +288,4 @@ def __eq__(self, other: Any) -> bool: # GridCoords objects are considered equal if they have the same cell_size and npix, since # all other attributes are derived from these two core properties. - return self.cell_size == other.cell_size and self.npix == other.npix + return bool(self.cell_size == other.cell_size and self.npix == other.npix) From 8391981b01dfd2ea8bba43e7d9df636d61f0ac75 Mon Sep 17 00:00:00 2001 From: Kadri Nizam Date: Wed, 5 Apr 2023 17:05:17 -0400 Subject: [PATCH 2/6] GridCoords repr and fix coordinates test --- src/mpol/coordinates.py | 3 +++ test/coordinates_test.py | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mpol/coordinates.py b/src/mpol/coordinates.py index 64f1ef4d..dbc368cb 100644 --- a/src/mpol/coordinates.py +++ b/src/mpol/coordinates.py @@ -78,6 +78,9 @@ def __init__(self, cell_size: float, npix: int): # max u or v freq supported by current grid self.max_grid = get_max_spatial_freq(cell_size, npix) + def __repr__(self): + return f"GridCoords(cell_size={self.cell_size:.2e}, npix={self.npix})" + @property def cell_size(self) -> float: return self._cell_size diff --git a/test/coordinates_test.py b/test/coordinates_test.py index d472c729..9bedbbac 100644 --- a/test/coordinates_test.py +++ b/test/coordinates_test.py @@ -75,7 +75,9 @@ def test_grid_coords_plot_2D_uvq_packed(tmp_path): def test_grid_coords_odd_fail(): - with pytest.raises(ValueError, match="Image must have an even number of pixels."): + with pytest.raises( + ValueError, match="Image must have a positive and even number of pixels." + ): coordinates.GridCoords(cell_size=0.01, npix=511) From e8a42bdbc3f33aa70b5f23081bd7ad255bf4bc1c Mon Sep 17 00:00:00 2001 From: Kadri Nizam Date: Wed, 5 Apr 2023 18:13:38 -0400 Subject: [PATCH 3/6] Fix wrong variable --- src/mpol/coordinates.py | 2 +- test/images_test.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mpol/coordinates.py b/src/mpol/coordinates.py index dbc368cb..a6e71f6c 100644 --- a/src/mpol/coordinates.py +++ b/src/mpol/coordinates.py @@ -70,7 +70,7 @@ def __init__(self, cell_size: float, npix: int): # Frequency related # These properties are identical for both u & v and defined here self._df = 1 / (npix * self._dimage) * 1e-3 # [kλ] - self._f_edges = self._dimage * (np.arange(npix + 1) - npix // 2 - 0.5) # [kλ] + self._f_edges = self._df * (np.arange(npix + 1) - npix // 2 - 0.5) # [kλ] self._f_centers = self._df * (np.arange(npix) - npix // 2) self._min_f = float(self._f_edges.min()) self._max_f = float(self._f_edges.max()) diff --git a/test/images_test.py b/test/images_test.py index 882cb257..2f33897a 100644 --- a/test/images_test.py +++ b/test/images_test.py @@ -8,7 +8,7 @@ def test_odd_npix(): - expected_error_message = "Image must have an even number of pixels." + expected_error_message = "Image must have a positive and even number of pixels." with pytest.raises(ValueError, match=expected_error_message): images.BaseCube.from_image_properties(npix=853, nchan=30, cell_size=0.015) @@ -189,7 +189,8 @@ def test_multi_chan_conv(coords, tmp_path): conv_layer(test_cube) + def test_image_flux(coords): nchan = 20 - im = images.ImageCube(coords=coords, nchan=nchan) + im = images.ImageCube(coords=coords, nchan=nchan) assert im.flux.size()[0] == nchan From 99f40586fb6eee16a2d4fb390e7e3c3ccf43d119 Mon Sep 17 00:00:00 2001 From: Kadri Nizam Date: Wed, 5 Apr 2023 19:35:27 -0400 Subject: [PATCH 4/6] Fix missing bracket and add meshgrid vs tile test --- src/mpol/coordinates.py | 4 ++-- test/coordinates_test.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/mpol/coordinates.py b/src/mpol/coordinates.py index a6e71f6c..22a52cf4 100644 --- a/src/mpol/coordinates.py +++ b/src/mpol/coordinates.py @@ -64,8 +64,8 @@ def __init__(self, cell_size: float, npix: int): self._npix = npix # Image related - self._dimage = self.cell_size * const.arcsec # [radians] - self._image_centers = self._dimage * np.arange(npix) - npix // 2 + self._dimage = cell_size * const.arcsec # [radians] + self._image_centers = self._dimage * (np.arange(npix) - npix // 2) # Frequency related # These properties are identical for both u & v and defined here diff --git a/test/coordinates_test.py b/test/coordinates_test.py index 9bedbbac..0b997c00 100644 --- a/test/coordinates_test.py +++ b/test/coordinates_test.py @@ -104,3 +104,20 @@ def test_grid_coords_fail(mock_visibility_data): with pytest.raises(CellSizeError): coords.check_data_fit(uu, vv) + + +def test_tile_vs_meshgrid_implementation(): + coords = coordinates.GridCoords(cell_size=0.05, npix=800) + + x_centers_2d, y_centers_2d = np.meshgrid( + coords.l_centers / arcsec, coords.m_centers / arcsec, indexing="xy" + ) + + sky_u_centers_2D, sky_v_centers_2D = np.meshgrid( + coords.u_centers, coords.v_centers, indexing="xy" + ) + + assert np.all(coords.sky_u_centers_2D == sky_u_centers_2D) + assert np.all(coords.sky_v_centers_2D == sky_v_centers_2D) + assert np.all(coords.x_centers_2D == x_centers_2d) + assert np.all(coords.y_centers_2D == y_centers_2d) From d648ac91c213158488c94ee002b38b6cfbc3e038 Mon Sep 17 00:00:00 2001 From: Kadri Nizam Date: Thu, 6 Apr 2023 12:01:40 -0400 Subject: [PATCH 5/6] Update src/mpol/coordinates.py Co-authored-by: Ian Czekala --- src/mpol/coordinates.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mpol/coordinates.py b/src/mpol/coordinates.py index 22a52cf4..ee0851dd 100644 --- a/src/mpol/coordinates.py +++ b/src/mpol/coordinates.py @@ -178,6 +178,7 @@ def vis_ext(self) -> list[float]: def sky_u_centers_2D(self) -> NDArray[floating[Any]]: # only useful for plotting a sky_vis # uu increasing, no fftshift + # tile replicates the 1D u_centers array to a 2D array the size of the full UV grid return np.tile(self.u_centers, (self.ncell_u, 1)) @cached_property From 63b9b771eaffb99d17d8923e09366625fa244e4a Mon Sep 17 00:00:00 2001 From: Kadri Nizam Date: Thu, 6 Apr 2023 12:06:52 -0400 Subject: [PATCH 6/6] Update uv variable names --- src/mpol/coordinates.py | 47 ++++++++++++++++++++-------------------- test/coordinates_test.py | 2 +- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/mpol/coordinates.py b/src/mpol/coordinates.py index 22a52cf4..8c53d85a 100644 --- a/src/mpol/coordinates.py +++ b/src/mpol/coordinates.py @@ -64,19 +64,20 @@ def __init__(self, cell_size: float, npix: int): self._npix = npix # Image related - self._dimage = cell_size * const.arcsec # [radians] - self._image_centers = self._dimage * (np.arange(npix) - npix // 2) + self._image_pixel_width = cell_size * const.arcsec # [radians] + self._image_centers = self._image_pixel_width * (np.arange(npix) - npix // 2) - # Frequency related + # Spatial frequency related # These properties are identical for both u & v and defined here - self._df = 1 / (npix * self._dimage) * 1e-3 # [kλ] - self._f_edges = self._df * (np.arange(npix + 1) - npix // 2 - 0.5) # [kλ] - self._f_centers = self._df * (np.arange(npix) - npix // 2) - self._min_f = float(self._f_edges.min()) - self._max_f = float(self._f_edges.max()) + # All units in [kλ] + self._uv_pixel_width = 1 / (npix * self._image_pixel_width) * 1e-3 + self.uv_edges = self._uv_pixel_width * (np.arange(npix + 1) - npix // 2 - 0.5) + self._uv_centers = self._uv_pixel_width * (np.arange(npix) - npix // 2) + self._min_uv = float(self.uv_edges.min()) + self._max_uv = float(self.uv_edges.max()) # max u or v freq supported by current grid - self.max_grid = get_max_spatial_freq(cell_size, npix) + self.max_uv_grid_value = get_max_spatial_freq(cell_size, npix) def __repr__(self): return f"GridCoords(cell_size={self.cell_size:.2e}, npix={self.npix})" @@ -91,11 +92,11 @@ def npix(self) -> int: @property def dl(self) -> float: - return self._dimage # [radians] + return self._image_pixel_width # [radians] @property def dm(self) -> float: - return self._dimage # [radians] + return self._image_pixel_width # [radians] @property def l_centers(self) -> NDArray[floating[Any]]: @@ -115,43 +116,43 @@ def ncell_v(self) -> int: @property def du(self) -> float: - return self._df + return self._uv_pixel_width @property def dv(self) -> float: - return self._df + return self._uv_pixel_width @property def u_edges(self) -> NDArray[floating[Any]]: - return self._f_edges + return self.uv_edges @property def v_edges(self) -> NDArray[floating[Any]]: - return self._f_edges + return self.uv_edges @property def u_centers(self) -> NDArray[floating[Any]]: - return self._f_centers + return self._uv_centers @property def v_centers(self) -> NDArray[floating[Any]]: - return self._f_centers + return self._uv_centers @property def u_bin_min(self) -> float: - return self._min_f + return self._min_uv @property def v_bin_min(self) -> float: - return self._min_f + return self._min_uv @property def u_bin_max(self) -> float: - return self._max_f + return self._max_uv @property def v_bin_max(self) -> float: - return self._max_f + return self._max_uv @property def img_ext(self) -> list[float]: @@ -270,14 +271,14 @@ def check_data_fit(self, uu: ArrayLike, vv: ArrayLike) -> None: # max freq needed to support dataset max_cell_size = get_maximum_cell_size(max_uu_vv) - if np.abs(uu).max() > self.max_grid: + if np.abs(uu).max() > self.max_uv_grid_value: raise CellSizeError( "Dataset contains uu spatial frequency measurements larger " "than those in the proposed model image. " f"Decrease cell_size below {max_cell_size} arcsec." ) - if np.abs(vv).max() > self.max_grid: + if np.abs(vv).max() > self.max_uv_grid_value: raise CellSizeError( "Dataset contains vv spatial frequency measurements larger " "than those in the proposed model image. " diff --git a/test/coordinates_test.py b/test/coordinates_test.py index 0b997c00..67bccceb 100644 --- a/test/coordinates_test.py +++ b/test/coordinates_test.py @@ -100,7 +100,7 @@ def test_grid_coords_fail(mock_visibility_data): coords = coordinates.GridCoords(cell_size=0.05, npix=800) print("max u data", np.max(uu)) - print("max u grid", coords.max_grid) + print("max u grid", coords.max_uv_grid_value) with pytest.raises(CellSizeError): coords.check_data_fit(uu, vv)