def _get_starpos(fwhm, position): starpos = np.zeros((nimages, 2), dtype=np.int64) if fwhm is None: starpos[:, 0] = position[0] starpos[:, 1] = position[1] else: if position is None: center = None width = None else: if position[0] is None and position[1] is None: center = None else: center = position[0:2] width = int(math.ceil(position[2] / pixscale)) for i, _ in enumerate(starpos): starpos[i, :] = locate_star( image=self.m_image_in_port[i, ], center=center, width=width, fwhm=int(math.ceil(fwhm / pixscale))) return starpos
def _crop_rotating_star(image, position, im_size, filter_size): starpos = locate_star(image=image, center=position, width=self.m_search_size, fwhm=filter_size) return crop_image(image=image, center=starpos, size=im_size)
def _crop_around_star(image, position, im_size, fwhm): if position is None: center = None width = None else: if position.ndim == 1: if position[0] is None and position[1] is None: center = None else: center = (int(position[1]), int(position[0])) width = int(math.ceil(position[2] / pixscale)) elif position.ndim == 2: center = (int(position[self.m_count, 1]), int(position[self.m_count, 0])) width = int(math.ceil(position[self.m_count, 2] / pixscale)) starpos = locate_star(image, center, width, fwhm) try: im_crop = crop_image(image, starpos, im_size) except ValueError: warnings.warn( "PSF size is too large to crop the image around the brightest " "pixel (image index = " + str(self.m_count) + ", pixel [x, y] = " + str([starpos[0]] + [starpos[1]]) + "). Using the center of the " "image instead.") index.append(self.m_count) starpos = image_center_pixel(image) im_crop = crop_image(image, starpos, im_size) star.append((starpos[1], starpos[0])) self.m_count += 1 return im_crop
def _crop_around_star(image, position, im_size, fwhm): if position is None: center = None width = None else: if position[0] is None and position[1] is None: center = None else: center = (position[1], position[0]) # (y, x) width = int(math.ceil(position[2] / pixscale)) starpos = locate_star(image, center, width, fwhm) try: im_crop = crop_image(image, starpos, im_size) except ValueError: if cpu == 1: warnings.warn( f'Chosen image size is too large to crop the image around the ' f'brightest pixel (image index = {self.m_count}, pixel [x, y] ' f'= [{starpos[0]}, {starpos[1]}]). Using the center of the ' f'image instead.') index.append(self.m_count) else: warnings.warn( 'Chosen image size is too large to crop the image around the ' 'brightest pixel. Using the center of the image instead.' ) starpos = center_pixel(image) im_crop = crop_image(image, starpos, im_size) if cpu == 1: star.append((starpos[1], starpos[0])) self.m_count += 1 return im_crop
def run(self): """ Run method of the module. Creates a PCA basis set of the background frames, masks the PSF in the star frames and optionally an off-axis point source, fits the star frames with a linear combination of the principal components, and writes the residuals of the background subtracted images. :return: None """ def _create_mask(radius, position, nimages): """ Method for creating a circular mask at the star or planet position. """ npix = self.m_star_in_port.get_shape()[1] x_grid = np.arange(0, npix, 1) y_grid = np.arange(0, npix, 1) xx_grid, yy_grid = np.meshgrid(x_grid, y_grid) mask = np.ones((nimages, npix, npix)) cent_x = position[:, 1] cent_y = position[:, 0] for i in range(nimages): rr_grid = np.sqrt((xx_grid - cent_x[i])**2 + (yy_grid - cent_y[i])**2) mask[i, ][rr_grid < radius] = 0. return mask def _create_basis(images, bg_mean, pca_number): """ Method for creating a set of principal components for a stack of images. """ if self.m_subtract_mean: images -= bg_mean _, _, v_svd = svds(images.reshape( images.shape[0], images.shape[1] * images.shape[2]), k=pca_number) v_svd = v_svd[::-1, ] pca_basis = v_svd.reshape(v_svd.shape[0], images.shape[1], images.shape[2]) return pca_basis def _model_background(basis, im_arr, mask): """ Method for creating a model of the background. """ def _dot_product(x_dot, *p): return np.dot(p, x_dot) fit_im_chi = np.zeros(im_arr.shape) # fit_coeff_chi = np.zeros((im_arr.shape[0], basis.shape[0])) basis_reshaped = basis.reshape(basis.shape[0], -1) for i in range(im_arr.shape[0]): basis_reshaped_masked = (basis * mask[i]).reshape( basis.shape[0], -1) data_to_fit = im_arr[i, ] init = np.ones(basis_reshaped_masked.shape[0]) fitted = curve_fit(_dot_product, basis_reshaped_masked, data_to_fit.reshape(-1), init) fit_im = np.dot(fitted[0], basis_reshaped) fit_im = fit_im.reshape(data_to_fit.shape[0], data_to_fit.shape[1]) fit_im_chi[i, ] = fit_im # fit_coeff_chi[i, ] = fitted[0] return fit_im_chi self.m_residuals_out_port.del_all_data() self.m_residuals_out_port.del_all_attributes() if self.m_fit_out_port is not None: self.m_fit_out_port.del_all_data() self.m_fit_out_port.del_all_attributes() if self.m_mask_out_port is not None: self.m_mask_out_port.del_all_data() self.m_mask_out_port.del_all_attributes() memory = self._m_config_port.get_attribute("MEMORY") pixscale = self.m_star_in_port.get_attribute("PIXSCALE") nimages = self.m_star_in_port.get_shape()[0] frames = memory_frames(memory, nimages) self.m_mask_star /= pixscale self.m_gaussian = int(math.ceil(self.m_gaussian / pixscale)) if self.m_subframe is not None: self.m_subframe /= pixscale self.m_subframe = int(math.ceil(self.m_subframe)) bg_mean = np.mean(self.m_background_in_port.get_all(), axis=0) star = np.zeros((nimages, 2)) for i, _ in enumerate(star): star[i, :] = locate_star(image=self.m_star_in_port[i, ] - bg_mean, center=None, width=self.m_subframe, fwhm=self.m_gaussian) if self.m_mask_planet is not None: parang = self.m_star_in_port.get_attribute("PARANG") self.m_mask_planet = np.asarray(self.m_mask_planet) self.m_mask_planet[0] /= pixscale self.m_mask_planet[3] /= pixscale sys.stdout.write("Creating PCA basis set...") sys.stdout.flush() basis_pca = _create_basis(self.m_background_in_port.get_all(), bg_mean, self.m_pca_number) sys.stdout.write(" [DONE]\n") sys.stdout.flush() for i, _ in enumerate(frames[:-1]): progress(i, len(frames[:-1]), "Calculating background model...") im_star = self.m_star_in_port[frames[i]:frames[i + 1], ] if self.m_subtract_mean: im_star -= bg_mean mask_star = _create_mask(self.m_mask_star, star[frames[i]:frames[i + 1], ], frames[i + 1] - frames[i]) if self.m_mask_planet is None: mask_planet = np.ones(im_star.shape) else: cent_x = star[frames[i]:frames[i + 1], 1] cent_y = star[frames[i]:frames[i + 1], 0] theta = np.radians(self.m_mask_planet[1] + 90. - \ parang[frames[i]:frames[i+1]] + self.m_mask_planet[2]) x_planet = self.m_mask_planet[0] * np.cos(theta) + cent_x y_planet = self.m_mask_planet[0] * np.sin(theta) + cent_y planet = np.stack((y_planet, x_planet)) mask_planet = _create_mask(self.m_mask_planet[3], np.transpose(planet), frames[i + 1] - frames[i]) fit_im = _model_background(basis_pca, im_star * mask_star * mask_planet, mask_star * mask_planet) self.m_residuals_out_port.append(im_star - fit_im) if self.m_fit_out_port is not None: self.m_fit_out_port.append(fit_im) if self.m_mask_out_port is not None: self.m_mask_out_port.append(mask_star * mask_planet) sys.stdout.write("Calculating background model... [DONE]\n") sys.stdout.flush() self.m_residuals_out_port.add_attribute("STAR_POSITION", star, static=False) self.m_residuals_out_port.copy_attributes_from_input_port( self.m_star_in_port) self.m_residuals_out_port.add_history_information( "Background subtraction", "PCA") if self.m_fit_out_port is not None: self.m_fit_out_port.copy_attributes_from_input_port( self.m_star_in_port) self.m_fit_out_port.add_history_information( "Background subtraction", "PCA") if self.m_mask_out_port is not None: self.m_mask_out_port.copy_attributes_from_input_port( self.m_star_in_port) self.m_mask_out_port.add_history_information( "Background subtraction", "PCA") self.m_residuals_out_port.close_port()