def pixel_var_psf(shape, var, psf_threshold=6): shape = data2np(shape, 'float') var = data2np(var, 'float') if len(shape) != 2: raise ValueError('Invalid shape length [%d]. 2D shape must have' 'length = 2.' % len(shape)) if len(var) != 2: raise ValueError('Invalid var length [%d]. 2D variance must have' 'length = 2.' % len(var)) # Define variance in x and y axes. var_2d_array = ((var / (np.floor(shape / 100.) * 100. + 100 * (shape < 100))) * np.array([np.arange(1, x) for x in shape + 1]).T).T # Define the shape of each pixel PSF. psf_shape = psf_threshold * var + 1 # Generate the PSF cube. pv_psf = [single_psf(psf_shape, x).T for x in np.array(list(product(*var_2d_array)), dtype='float')] return np.array(pv_psf).T
def psf_var_convolve(image, psf): # Function to select slices of an image. def select_slices(image_shape, sub_shape): ranges = np.array([np.arange(i) for i in image_shape]) limits = np.array([ranges.T + sub_shape / 2 + 1, ranges.T + 1.5 * sub_shape + 1]).T return np.array([np.array([slice(*i), slice(*j)]) for i in limits[0] for j in limits[1]]) # Function to convolve a PSF with a sub-image. def get_convolve(sub_image, psf): return np.multiply(sub_image, np.rot90(psf, 2)).sum() # Pad image borders by PSF size. image_pad = pad2d(image, psf.shape[1:]) # Get sub-image slices of the padded image. slices = select_slices(image.shape, data2np(psf.shape[1:])) # Convolve sub-images with PSFs. image_conv = np.array([[get_convolve(image_pad[list(x)], y)] for x, y in zip(slices, psf)]) return np.reshape(image_conv, image.shape)
def _window(self, pos, func=None): pos = data2np(pos) if pos.size != 2: raise ValueError('The pixel position must have a size of 2.') window = self.pad_data[[slice(a - b, a + b + 1) for a, b in izip(pos, self.pixel_rad)]] if isinstance(func, type(None)): return window else: return func(window)
def map2matrix(data_map, layout): """Map to Matrix This method transforms a 2D map to a 2D matrix Parameters ---------- data_map : np.ndarray Input data map, 2D array layout : tuple 2D layout of 2D images Returns ------- np.ndarray 2D matrix Raises ------ ValueError For invalid layout """ layout = data2np(layout) # Select n objects n_obj = np.prod(layout) # Get the shape of the galaxy images gal_shape = (data2np(data_map.shape) / layout)[0] # Stack objects from map data_matrix = [] for i in range(n_obj): lower = (gal_shape * (i / layout[1]), gal_shape * (i % layout[1])) upper = (gal_shape * (i / layout[1] + 1), gal_shape * (i % layout[1] + 1)) data_matrix.append((data_map[lower[0]:upper[0], lower[1]:upper[1]]).reshape(gal_shape**2)) return np.array(data_matrix).T
def _window(self, pos, func=None, *args): pos = data2np(pos) if pos.size != 2: raise ValueError('The pixel position must have a size of 2.') window = self.pad_data[[ slice(a - b, a + b + 1) for a, b in izip(pos, self.pixel_rad) ]] if isinstance(func, type(None)): return window else: return func(window, *args)
def single_psf(shape, var): # Convert inputs to Numpy arrays shape = data2np(shape) var = data2np(var) if len(shape) != 2: raise ValueError('Invalid shape length [%d]. 2D shape must have' 'length = 2.' % len(shape)) if len(var) != 2: raise ValueError('Invalid var length [%d]. 2D variance must have' 'length = 2.' % len(var)) # Single pixel point psf = np.zeros(shape) psf[zip(shape / 2)] = 1 # Gaussian filter with given variance psf = gaussian_filter(psf, var) return psf / psf.sum()
def map2matrix(data_map, layout): layout = data2np(layout) # Select n objects n_obj = np.prod(layout) # Get the shape of the galaxy images gal_shape = (data2np(data_map.shape) / layout)[0] # Stack objects from map data_matrix = [] for i in range(n_obj): lower = (gal_shape * (i / layout[1]), gal_shape * (i % layout[1])) upper = (gal_shape * (i / layout[1] + 1), gal_shape * (i % layout[1] + 1)) data_matrix.append((data_map[lower[0]:upper[0], lower[1]:upper[1]]).reshape(gal_shape ** 2)) return np.array(data_matrix).T
def cube2map(data_cube, layout): layout = data2np(layout) # Select n objects n_obj = np.prod(layout) temp = data_cube[:, :, :n_obj] # Map objects from cube data_map = np.zeros((layout * temp.shape[:2])) for i in range(n_obj): lower = (temp.shape[0] * (i / layout[1]), temp.shape[0] * (i % layout[1])) upper = (temp.shape[0] * (i / layout[1] + 1), temp.shape[0] * (i % layout[1] + 1)) data_map[lower[0]:upper[0], lower[1]:upper[1]] = temp[:, :, i] return data_map
def matrix2map(data_matrix, map_shape): """Matrix to Map This method transforms a 2D matrix to a 2D map Parameters ---------- data_matrix : np.ndarray Input data matrix, 2D array map_shape : tuple 2D shape of the output map Returns ------- np.ndarray 2D map Raises ------ ValueError For invalid layout """ map_shape = data2np(map_shape) # Get the shape and layout of the galaxy images gal_shape = np.sqrt(data_matrix.shape[0]) layout = np.array(map_shape / np.repeat(gal_shape, 2), dtype='int') # Map objects from matrix data_map = np.zeros(map_shape) temp = data_matrix.reshape(gal_shape, gal_shape, data_matrix.shape[1]) for i in range(data_matrix.shape[1]): lower = (gal_shape * (i / layout[1]), gal_shape * (i % layout[1])) upper = (gal_shape * (i / layout[1] + 1), gal_shape * (i % layout[1] + 1)) data_map[lower[0]:upper[0], lower[1]:upper[1]] = temp[:, :, i] return data_map
def matrix2map(data_matrix, map_shape): map_shape = data2np(map_shape) # Get the shape and layout of the galaxy images gal_shape = np.sqrt(data_matrix.shape[0]) layout = np.array(map_shape / np.repeat(gal_shape, 2), dtype='int') # Map objects from matrix data_map = np.zeros(map_shape) temp = data_matrix.reshape(gal_shape, gal_shape, data_matrix.shape[1]) for i in range(data_matrix.shape[1]): lower = (gal_shape * (i / layout[1]), gal_shape * (i % layout[1])) upper = (gal_shape * (i / layout[1] + 1), gal_shape * (i % layout[1] + 1)) data_map[lower[0]:upper[0], lower[1]:upper[1]] = temp[:, :, i] return data_map
def psf_pca_parts(psf, thresholds, n_pieces, return_coef=True, coef_shape=None): # Convert inputs to Numpy arrays thresholds = data2np(thresholds) # Split the PSF into pieces. pieces = np.split(psf, np.arange(1, n_pieces) * psf.shape[2] / n_pieces, axis=2) # Get the princicpal components for each of the pieces. res = [psf_pca(piece, thresholds[0], 'full', False) for piece in pieces] psf_pcs_pieces = np.vstack([val.T for val in res]).T # Get the final princicpal components. psf_pcs = psf_pca(psf_pcs_pieces, thresholds[1], 'full', False) if return_coef: # Get the PCA coefficients. return psf_pcs, get_coef(psf, psf_pcs, coef_shape) else: return psf_pcs