Source code for corgidrp.find_source

import numpy as np
from pyklip.kpp.metrics.crossCorr import calculate_cc
from pyklip.kpp.stat.statPerPix_utils import get_image_stat_map_perPixMasking

[docs] def make_snmap(image, psf_binarymask, image_without_planet=None, coronagraph=True): """ Generates a signal-to-noise (S/N) map by convolving the image with the PSF. Args: image (ndarray): The input image. psf_binarymask (ndarray): A binary mask for PSF convolution. image_without_planet (ndarray, optional): An image without any sources (~noise map) to make snmap more accurate. coronagraph (bool, optional): If True, an IWA is applied to derive the snmap. Defaults to True. Returns: ndarray: The computed S/N map. """ image_convo = calculate_cc(image, psf_binarymask, nans2zero=True) if image_without_planet is not None: image_wop_convo = calculate_cc(image_without_planet, psf_binarymask, nans2zero=True) else: image_wop_convo = None if coronagraph: # Compute distance map from PSF center and mask radius from the image. x = np.arange(image.shape[1]) ; y = np.arange(image.shape[0]) xx, yy = np.meshgrid(x, y) center = np.array(image.shape) // 2 distance_map = np.sqrt((xx - center[1])**2 + (yy - center[0])**2) idx = np.where( (np.isnan(image) == False) ) mask_radius = np.ceil( np.min(distance_map[idx]) ) else: mask_radius = 0. image_snmap = get_image_stat_map_perPixMasking(image_convo, image_without_planet=image_wop_convo, mask_radius=mask_radius, Dr=3.) return image_snmap
[docs] def psf_scalesub(image, xy, psf, fwhm): """ Scales and subtracts the PSF at a given location in the image. Args: image (ndarray): The input image. xy (tuple): The (y, x) coordinates where the PSF should be subtracted. psf (ndarray): The point spread function. fwhm (float): Full width at half maximum of the PSF. Returns: ndarray: The image after PSF subtraction. """ # Compute distance map from PSF center x = np.arange(psf.shape[1]) ; y = np.arange(psf.shape[0]) xx, yy = np.meshgrid(x, y) center = np.array(psf.shape) // 2 distance_map = np.sqrt((xx - center[1])**2 + (yy - center[0])**2) # Scale PSF to match local flux and subtract it psf_window = psf.shape[0] // 2 #PSF: square array im_row_start = xy[0]-psf_window im_row_end = xy[0]+psf_window+1 im_col_start = xy[1]-psf_window im_col_end = xy[1]+psf_window+1 row_off_start = xy[0]-psf_window if row_off_start >= 0: row_off_start = 0 else: im_row_start = 0 row_off_end = image.shape[0] - (xy[0]+psf_window+1) if row_off_end >= 0: row_off_end = None else: im_row_end = None col_off_start = xy[1]-psf_window if col_off_start >= 0: col_off_start = 0 else: im_col_start = 0 col_off_end = image.shape[1] - (xy[1]+psf_window+1) if col_off_end >= 0: col_off_end = None else: im_col_end = None psf_scaled = psf[-row_off_start:row_off_end, -col_off_start:col_off_end] * np.nanmedian(image[ im_row_start:im_row_end, im_col_start:im_col_end] / psf[-row_off_start:row_off_end, -col_off_start:col_off_end]) # Mask central region of the PSF idx_masked = np.where( (distance_map[-row_off_start:row_off_end, -col_off_start:col_off_end] < fwhm*1.0) ) psf_scaled[idx_masked] = np.nan # Apply masking image[im_row_start:im_row_end, im_col_start:im_col_end] -= psf_scaled return image