def convolved_array_from_array_and_mask(self, array, mask): """ Convolve an array with this Kernel2D Parameters ---------- image : np.ndarray An array representing the image the Kernel2D is convolved with. Returns ------- convolved_image : np.ndarray An array representing the image after convolution. Raises ------ KernelException if either Kernel2D psf dimension is odd """ if self.mask.shape[0] % 2 == 0 or self.mask.shape[1] % 2 == 0: raise exc.KernelException("Kernel2D Kernel2D must be odd") convolved_array_2d = scipy.signal.convolve2d(array, self.native, mode="same") convolved_array_1d = array_2d_util.array_2d_slim_from( mask_2d=mask, array_2d_native=convolved_array_2d, sub_size=1) return array_2d.Array2D(array=convolved_array_1d, mask=mask.mask_sub_1)
def grid_2d_slim_from(grid_2d_native: np.ndarray, mask: np.ndarray, sub_size: int) -> np.ndarray: """ For a native 2D grid and mask of shape [total_y_pixels, total_x_pixels, 2], map the values of all unmasked pixels to a slimmed grid of shape [total_unmasked_pixels, 2]. The pixel coordinate origin is at the top left corner of the native grid and goes right-wards and downwards, such that for an grid of shape (3,3) where all pixels are unmasked: - pixel [0,0] of the 2D grid will correspond to index 0 of the 1D grid. - pixel [0,1] of the 2D grid will correspond to index 1 of the 1D grid. - pixel [1,0] of the 2D grid will correspond to index 4 of the 1D grid. Parameters ---------- grid_2d_native : ndarray The native grid of (y,x) values which are mapped to the slimmed grid. mask_2d : np.ndarray A 2D array of bools, where `False` values mean unmasked and are included in the mapping. sub_size : int The size (sub_size x sub_size) of each unmasked pixels sub-array. Returns ------- ndarray A 1D grid of values mapped from the 2D grid with dimensions (total_unmasked_pixels). """ grid_1d_slim_y = array_2d_util.array_2d_slim_from( array_2d_native=grid_2d_native[:, :, 0], mask_2d=mask, sub_size=sub_size) grid_1d_slim_x = array_2d_util.array_2d_slim_from( array_2d_native=grid_2d_native[:, :, 1], mask_2d=mask, sub_size=sub_size) return np.stack((grid_1d_slim_y, grid_1d_slim_x), axis=-1)
def slim(self): """ Return an `Array2D` where the data is stored its `slim` representation, which is an ndarray of shape [total_unmasked_pixels * sub_size**2]. If it is already stored in its `slim` representation it is returned as it is. If not, it is mapped from `native` to `slim` and returned as a new `Array2D`. """ if len(self.shape) == 1: return self sub_array_1d = array_2d_util.array_2d_slim_from( array_2d_native=self, mask_2d=self.mask, sub_size=self.mask.sub_size ) return self._new_structure(array=sub_array_1d, mask=self.mask)
def convert_array_2d(array_2d, mask_2d): """ Manual array functions take as input a list or ndarray which is to be returned as an Array2D. This function performs the following and checks and conversions on the input: 1) If the input is a list, convert it to an ndarray. 2) Check that the number of sub-pixels in the array is identical to that of the mask. 3) Map the input ndarray to its `slim` representation. For an Array2D, `slim` refers to a 1D NumPy array of shape [total_values] and `native` a 2D NumPy array of shape [total_y_values, total_values]. Parameters ---------- array_2d : np.ndarray or list The input structure which is converted to an ndarray if it is a list. mask_2d : Mask2D The mask of the output Array2D. """ array_2d = abstract_array.convert_array(array=array_2d) if len(array_2d.shape) == 1: array_2d_slim = abstract_array.convert_array(array=array_2d) if array_2d_slim.shape[0] != mask_2d.sub_pixels_in_mask: raise exc.ArrayException( "The input 1D array does not have the same number of entries as sub-pixels in" "the mask." ) return array_2d_slim if array_2d.shape != mask_2d.sub_shape_native: raise exc.ArrayException( "The input array is 2D but not the same dimensions as the sub-mask " "(e.g. the mask 2D shape multipled by its sub size." ) sub_array_1d = array_2d_util.array_2d_slim_from( array_2d_native=array_2d, mask_2d=mask_2d, sub_size=mask_2d.sub_size ) return sub_array_1d
def return_iterated_array_result( self, iterated_array: np.ndarray) -> array_2d.Array2D: """ Returns the resulting iterated array, by mapping it to 1D and then passing it back as an `Array2D` structure. Parameters ---------- iterated_array : np.ndarray Returns ------- iterated_array The resulting array computed via iteration. """ iterated_array_1d = array_2d_util.array_2d_slim_from( mask_2d=self.mask, array_2d_native=iterated_array, sub_size=1) return array_2d.Array2D(array=iterated_array_1d, mask=self.mask.mask_sub_1)