def manual_mask(cls, array, mask): """ Create a Line (see `Line.__new__`) by inputting the native line values in 1D and including the mask that is applied to them, for example: mask=np.array([True, False, False, True, False, False]) line=np.array([100.0, 1.0, 2.0, 100.0, 3.0 4.0]) line=[100.0, 1.0, 2.0, 100.0, 3.0, 4.0] Parameters ---------- array : np.ndarray or list The values of the line input as an ndarray of shape [total_unmasked_pixels*sub_size] or a list. pixel_scales: float The scaled units to pixel units conversion factor of the line data coordinates (e.g. the x-axis). sub_size : int The size of each unmasked pixels sub-gridded line. origin : (float, float) The origin of the line's mask. """ array = abstract_array.convert_array(array) array = array_1d_util.array_1d_slim_from( array_1d_native=array, mask_1d=mask, sub_size=mask.sub_size ) return Array1D(array=array, mask=mask)
def manual_slim(cls, array, pixel_scales, sub_size=1, origin=(0.0,)): """ Create a Line (see `Line.__new__`) by inputting the line values in 1D, for example: line=np.array([1.0, 2.0 3.0, 4.0]) line=[1.0, 2.0, 3.0, 4.0] Parameters ---------- array : np.ndarray or list The values of the line input as an ndarray of shape [total_unmasked_pixels*sub_size] or a list. pixel_scales: float The scaled units to pixel units conversion factor of the line data coordinates (e.g. the x-axis). sub_size : int The size of each unmasked pixels sub-gridded line. origin : (float, ) The origin of the line's mask. """ array = abstract_array.convert_array(array) pixel_scales = geometry_util.convert_pixel_scales_1d(pixel_scales=pixel_scales) mask = msk.Mask1D.unmasked( shape_slim=array.shape[0] // sub_size, pixel_scales=pixel_scales, sub_size=sub_size, origin=origin, ) return Array1D(array=array, mask=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 manual( cls, array, pixel_scales, shape_native=None, sub_size=1, origin=(0.0, 0.0), exposure_info=None, ): """Create an Array2D (see `AbstractArray2D.__new__`) by inputting the array values in 1D or 2D, automatically determining whether to use the 'manual_slim' or 'manual_native' methods. See the manual_slim and manual_native methods for examples. Parameters ---------- array : np.ndarray or list The values of the array input as an ndarray of shape [total_unmasked_pixels*(sub_size**2)] or a list of lists. shape_native : (int, int) The 2D shape of the mask the array is paired with. pixel_scales: (float, float) or float The (y,x) scaled units to pixel units conversion factors of every pixel. If this is input as a ``float``, it is converted to a (float, float) structure. sub_size : int The size (sub_size x sub_size) of each unmasked pixels sub-array. origin : (float, float) The (y,x) scaled units origin of the mask's coordinate system. """ array = abstract_array.convert_array(array=array) if len(array.shape) == 1: return cls.manual_slim( array=array, pixel_scales=pixel_scales, shape_native=shape_native, sub_size=sub_size, origin=origin, ) return cls.manual_native( array=array, pixel_scales=pixel_scales, sub_size=sub_size, origin=origin, exposure_info=exposure_info, )
def manual_native( cls, array, pixel_scales, sub_size=1, origin=(0.0, 0.0), exposure_info=None ): """Create an Array2D (see `AbstractArray2D.__new__`) by inputting the array values in 2D, for example: array=np.ndarray([[1.0, 2.0], [3.0, 4.0]]) array=[[1.0, 2.0], [3.0, 4.0]] The 2D shape of the array and its mask are determined from the input array and the mask is setup as an unmasked `Mask2D` of shape_native. Parameters ---------- array : np.ndarray or list The values of the array input as an ndarray of shape [total_y_pixels*sub_size, total_x_pixel*sub_size] or a list of lists. pixel_scales: (float, float) or float The (y,x) scaled units to pixel units conversion factors of every pixel. If this is input as a ``float``, it is converted to a (float, float) structure. sub_size : int The size (sub_size x sub_size) of each unmasked pixels sub-array. origin : (float, float) The (y,x) scaled units origin of the mask's coordinate system. """ pixel_scales = geometry_util.convert_pixel_scales_2d(pixel_scales=pixel_scales) array = abstract_array.convert_array(array=array) shape_native = (int(array.shape[0] / sub_size), int(array.shape[1] / sub_size)) mask = msk.Mask2D.unmasked( shape_native=shape_native, pixel_scales=pixel_scales, sub_size=sub_size, origin=origin, ) array = abstract_array_2d.convert_array_2d(array_2d=array, mask_2d=mask) return cls(array=array, mask=mask, exposure_info=exposure_info)
def __new__( cls, array, mask, exposure_info=None, zoom_for_plot=True, *args, **kwargs ): """ An array of values, which are paired to a uniform 2D mask of pixels and sub-pixels. Each entry on the array corresponds to a value at the centre of a sub-pixel in an unmasked pixel. An *Array2D* is ordered such that pixels begin from the top-row of the corresponding mask and go right and down. The positive y-axis is upwards and positive x-axis to the right. The array can be stored in 1D or 2D, as detailed below. Case 1: [sub-size=1, slim]: ----------------------------------------- The Array2D is an ndarray of shape [total_unmasked_pixels]. The first element of the ndarray corresponds to the pixel index, for example: - array[3] = the 4th unmasked pixel's value. - array[6] = the 7th unmasked pixel's value. Below is a visual illustration of a array, where a total of 10 pixels are unmasked and are included in \ the array. IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI This is an example mask.Mask2D, where: IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIoIoIxIxIxIxI x = `True` (Pixel is masked and excluded from the array) IxIxIxIoIoIoIoIxIxIxI o = `False` (Pixel is not masked and included in the array) IxIxIxIoIoIoIoIxIxIxI IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI The mask pixel index's will come out like this (and the direction of scaled values is highlighted around the mask. pixel_scales = 1.0" <--- -ve x +ve --> y x IxIxIxIxIxIxIxIxIxIxI ^ array[0] = 0 IxIxIxIxIxIxIxIxIxIxI I array[1] = 1 IxIxIxIxIxIxIxIxIxIxI I array[2] = 2 IxIxIxIxI0I1IxIxIxIxI +ve array[3] = 3 IxIxIxI2I3I4I5IxIxIxI y array[4] = 4 IxIxIxI6I7I8I9IxIxIxI -ve array[5] = 5 IxIxIxIxIxIxIxIxIxIxI I array[6] = 6 IxIxIxIxIxIxIxIxIxIxI I array[7] = 7 IxIxIxIxIxIxIxIxIxIxI \/ array[8] = 8 IxIxIxIxIxIxIxIxIxIxI array[9] = 9 Case 2: [sub-size>1, slim]: ------------------ If the masks's sub size is > 1, the array is defined as a sub-array where each entry corresponds to the values at the centre of each sub-pixel of an unmasked pixel. The sub-array indexes are ordered such that pixels begin from the first (top-left) sub-pixel in the first unmasked pixel. Indexes then go over the sub-pixels in each unmasked pixel, for every unmasked pixel. Therefore, the sub-array is an ndarray of shape [total_unmasked_pixels*(sub_array_shape)**2]. For example: - array[9] - using a 2x2 sub-array, gives the 3rd unmasked pixel's 2nd sub-pixel value. - array[9] - using a 3x3 sub-array, gives the 2nd unmasked pixel's 1st sub-pixel value. - array[27] - using a 3x3 sub-array, gives the 4th unmasked pixel's 1st sub-pixel value. Below is a visual illustration of a sub array. Indexing of each sub-pixel goes from the top-left corner. In contrast to the array above, our illustration below restricts the mask to just 2 pixels, to keep the illustration brief. IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI This is an example mask.Mask2D, where: IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI x = `True` (Pixel is masked and excluded from lens) IxIxIxIxIoIoIxIxIxIxI o = `False` (Pixel is not masked and included in lens) IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI Our array with a sub-size looks like it did before: pixel_scales = 1.0" <--- -ve x +ve --> IxIxIxIxIxIxIxIxIxIxI ^ IxIxIxIxIxIxIxIxIxIxI I IxIxIxIxIxIxIxIxIxIxI I IxIxIxIxIxIxIxIxIxIxI +ve IxIxIxI0I1IxIxIxIxIxI y IxIxIxIxIxIxIxIxIxIxI -ve IxIxIxIxIxIxIxIxIxIxI I IxIxIxIxIxIxIxIxIxIxI I IxIxIxIxIxIxIxIxIxIxI \/ IxIxIxIxIxIxIxIxIxIxI However, if the sub-size is 2,each unmasked pixel has a set of sub-pixels with values. For example, for pixel 0, if *sub_size=2*, it has 4 values on a 2x2 sub-array: Pixel 0 - (2x2): array[0] = value of first sub-pixel in pixel 0. I0I1I array[1] = value of first sub-pixel in pixel 1. I2I3I array[2] = value of first sub-pixel in pixel 2. array[3] = value of first sub-pixel in pixel 3. If we used a sub_size of 3, for the first pixel we we would create a 3x3 sub-array: array[0] = value of first sub-pixel in pixel 0. array[1] = value of first sub-pixel in pixel 1. array[2] = value of first sub-pixel in pixel 2. I0I1I2I array[3] = value of first sub-pixel in pixel 3. I3I4I5I array[4] = value of first sub-pixel in pixel 4. I6I7I8I array[5] = value of first sub-pixel in pixel 5. array[6] = value of first sub-pixel in pixel 6. array[7] = value of first sub-pixel in pixel 7. array[8] = value of first sub-pixel in pixel 8. Case 3: [sub_size=1, native] -------------------------------------- The Array2D has the same properties as Case 1, but is stored as an an ndarray of shape [total_y_values, total_x_values]. All masked entries on the array have values of 0.0. For the following example mask: IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI This is an example mask.Mask2D, where: IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIoIoIxIxIxIxI x = `True` (Pixel is masked and excluded from the array) IxIxIxIoIoIoIoIxIxIxI o = `False` (Pixel is not masked and included in the array) IxIxIxIoIoIoIoIxIxIxI IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI IxIxIxIxIxIxIxIxIxIxI - array[0,0] = 0.0 (it is masked, thus zero) - array[0,0] = 0.0 (it is masked, thus zero) - array[3,3] = 0.0 (it is masked, thus zero) - array[3,3] = 0.0 (it is masked, thus zero) - array[3,4] = 0 - array[3,4] = -1 Case 4: [sub_size>, native] -------------------------------------- The properties of this array can be derived by combining Case's 2 and 3 above, whereby the array is stored as an ndarray of shape [total_y_values*sub_size, total_x_values*sub_size]. All sub-pixels in masked pixels have values 0.0. Parameters ---------- array : np.ndarray The values of the array. mask : msk.Mask2D The 2D mask associated with the array, defining the pixels each array value is paired with and originates from. """ array = abstract_array.convert_array(array=array) obj = array.view(cls) obj.mask = mask obj.exposure_info = exposure_info obj.zoom_for_plot = zoom_for_plot return obj