def check_grid_2d(grid_2d): if grid_2d.shape[-1] != 2: raise exc.GridException( "The final dimension of the input grid is not equal to 2 (e.g. the (y,x) coordinates)" ) if 2 < len(grid_2d.shape) > 3: raise exc.GridException( "The dimensions of the input grid array is not 2 or 3")
def check_grid_2d_and_mask_2d(grid_2d, mask_2d): if len(grid_2d.shape) == 2: if grid_2d.shape[0] != mask_2d.sub_pixels_in_mask: raise exc.GridException( "The input 1D grid does not have the same number of entries as sub-pixels in" "the mask.") elif len(grid_2d.shape) == 3: if (grid_2d.shape[0], grid_2d.shape[1]) != mask_2d.sub_shape_native: raise exc.GridException( "The input grid is 2D but not the same dimensions as the sub-mask " "(e.g. the mask 2D shape multipled by its sub size.")
def manual_mask(cls, grid, mask): """ Create a Grid1D (see `Grid1D.__new__`) by inputting the grid coordinates in 1D with their corresponding mask. See the manual_slim and manual_native methods for examples. Parameters ---------- grid : np.ndarray or list The (x) coordinates of the grid input as an ndarray of shape [total_coordinates*sub_size] or a list of lists. mask : msk.Mask1D The 1D mask associated with the grid, defining the pixels each grid coordinate is paired with and originates from. """ grid = abstract_grid.convert_grid(grid=grid) if grid.shape[0] == mask.sub_shape_native[0]: grid = grid_1d_util.grid_1d_slim_from(grid_1d_native=grid, mask_1d=mask, sub_size=mask.sub_size) elif grid.shape[0] != mask.shape[0]: raise exc.GridException( "The grid input into manual_mask does not have matching dimensions with the mask" ) return Grid1D(grid=grid, mask=mask)
def pixel_scale(self): if self.pixel_scales[0] == self.pixel_scales[1]: return self.pixel_scales[0] else: raise exc.GridException( "Cannot return a pixel_scale for a grid where each dimension has a " "different pixel scale (e.g. pixel_scales[0] != pixel_scales[1]" )
def wrapper(obj, grid, *args, **kwargs) -> Union[array_1d.Array1D, values.ValuesIrregular]: """ This decorator homogenizes the input of a "grid_like" 2D structure (`Grid2D`, `Grid2DIterate`, `Grid2DInterpolate`, `Grid2DIrregular` or `AbstractGrid1D`) into a function. It allows these classes to be interchangeably input into a function, such that the grid is used to evaluate the function at every (y,x) coordinates of the grid using specific functionality of the input grid. The grid_like objects `Grid2D` and `Grid2DIrregular` are input into the function as a slimmed 2D NumPy array of shape [total_coordinates, 2] where the second dimension stores the (y,x) values. If a `Grid2DIterate` is input, the function is evaluated using the appropriate iterated_*_from_func* function. The outputs of the function are converted from a 1D or 2D NumPy Array2D to an `Array2D`, `Grid2D`, `ValuesIrregular` or `Grid2DIrregular` objects, whichever is applicable as follows: - If the function returns (y,x) coordinates at every input point, the returned results are a `Grid2D` or `Grid2DIrregular` structure, the same structure as the input. - If the function returns scalar values at every input point and a `Grid2D` is input, the returned results are an `Array2D` structure which uses the same dimensions and mask as the `Grid2D`. - If the function returns scalar values at every input point and `Grid2DIrregular` are input, the returned results are a `ValuesIrregular` object with structure resembling that of the `Grid2DIrregular`. If the input array is not a `Grid2D` structure (e.g. it is a 2D NumPy array) the output is a NumPy array. Parameters ---------- obj : object An object whose function uses grid_like inputs to compute quantities at every coordinate on the grid. grid : Grid2D or Grid2DIrregular A grid_like object of (y,x) coordinates on which the function values are evaluated. Returns ------- The function values evaluated on the grid with the same structure as the input grid_like object. """ result = func(obj, grid, *args, **kwargs) if (isinstance(grid, grid_2d.Grid2D) or isinstance(grid, grid_2d_iterate.Grid2DIterate) or isinstance(grid, grid_2d_interpolate.Grid2DInterpolate)): return array_1d.Array1D.manual_slim(array=result, pixel_scales=grid.pixel_scale) elif isinstance(grid, grid_2d_irregular.Grid2DIrregular): return grid.structure_2d_from_result(result=result) elif isinstance(grid, abstract_grid_1d.AbstractGrid1D): return array_1d.Array1D.manual_slim(array=result, pixel_scales=grid.pixel_scale) raise exc.GridException( "You cannot input a NumPy array to a `quantity_1d_from_grid` method." )
def manual_1d(cls, grid, mask, store_in_1d=True): if type(grid) is list: grid = np.asarray(grid) if grid.shape[0] != mask.sub_pixels_in_mask: raise exc.GridException( "The input 1D grid does not have the same number of entries as sub-pixels in" "the mask.") if store_in_1d: return mask.mapping.grid_stored_1d_from_sub_grid_1d( sub_grid_1d=grid) else: return mask.mapping.grid_stored_2d_from_sub_grid_1d( sub_grid_1d=grid)
def manual_2d(cls, grid, mask, store_in_1d=True): if type(grid) is list: grid = np.asarray(grid) if (grid.shape[0], grid.shape[1]) != mask.sub_shape_2d: raise exc.GridException( "The input grid is 2D but not the same dimensions as the sub-mask " "(e.g. the mask 2D shape multipled by its sub size.") if store_in_1d: return mask.mapping.grid_stored_1d_from_sub_grid_2d( sub_grid_2d=grid) else: sub_grid_1d = mask.mapping.grid_stored_1d_from_sub_grid_2d( sub_grid_2d=grid) return mask.mapping.grid_stored_2d_from_sub_grid_1d( sub_grid_1d=sub_grid_1d)