Ejemplo n.º 1
0
        def _objective(arg):
            sys.stdout.write('.')
            sys.stdout.flush()

            pos_y = arg[0]
            pos_x = arg[1]
            mag = arg[2]

            sep_ang = cartesian_to_polar(center, pos_y, pos_x)

            fake = fake_planet(images=images,
                               psf=psf,
                               parang=parang,
                               position=(sep_ang[0], sep_ang[1]),
                               magnitude=mag,
                               psf_scaling=self.m_psf_scaling)

            mask = create_mask(fake.shape[-2:], (self.m_cent_size, self.m_edge_size))

            if self.m_reference_in_port is None:
                _, im_res = pca_psf_subtraction(images=fake*mask,
                                                angles=-1.*parang+self.m_extra_rot,
                                                pca_number=self.m_pca_number,
                                                pca_sklearn=None,
                                                im_shape=None,
                                                indices=None)

            else:
                im_reshape = np.reshape(fake*mask, (im_shape[0], im_shape[1]*im_shape[2]))

                _, im_res = pca_psf_subtraction(images=im_reshape,
                                                angles=-1.*parang+self.m_extra_rot,
                                                pca_number=self.m_pca_number,
                                                pca_sklearn=sklearn_pca,
                                                im_shape=im_shape,
                                                indices=None)

            res_stack = combine_residuals(method=self.m_residuals, res_rot=im_res)

            self.m_res_out_port.append(res_stack, data_dim=3)

            chi_square = merit_function(residuals=res_stack[0, ],
                                        merit=self.m_merit,
                                        aperture=aperture,
                                        sigma=self.m_sigma)

            position = rotate_coordinates(center, (pos_y, pos_x), -self.m_extra_rot)

            res = np.asarray([position[1],
                              position[0],
                              sep_ang[0]*pixscale,
                              (sep_ang[1]-self.m_extra_rot) % 360.,
                              mag,
                              chi_square])

            self.m_flux_position_port.append(res, data_dim=2)

            return chi_square
Ejemplo n.º 2
0
        def _objective(arg):
            sys.stdout.write('.')
            sys.stdout.flush()

            pos_y = arg[0]
            pos_x = arg[1]
            mag = arg[2]

            sep_ang = cartesian_to_polar(center, pos_x, pos_y)

            fake = fake_planet(images=images,
                               psf=psf,
                               parang=parang,
                               position=(sep_ang[0], sep_ang[1]),
                               magnitude=mag,
                               psf_scaling=self.m_psf_scaling)

            im_shape = (fake.shape[-2], fake.shape[-1])

            mask = create_mask(im_shape, [self.m_cent_size, self.m_edge_size])

            _, im_res = pca_psf_subtraction(images=fake*mask,
                                            angles=-1.*parang+self.m_extra_rot,
                                            pca_number=self.m_pca_number)

            stack = combine_residuals(method=self.m_residuals, res_rot=im_res)

            self.m_res_out_port.append(stack, data_dim=3)

            merit = merit_function(residuals=stack[0, ],
                                   function=self.m_merit,
                                   variance="poisson",
                                   aperture=self.m_aperture,
                                   sigma=self.m_sigma)

            position = rotate_coordinates(center, (pos_y, pos_x), -self.m_extra_rot)

            res = np.asarray((position[1],
                              position[0],
                              sep_ang[0]*pixscale,
                              (sep_ang[1]-self.m_extra_rot)%360.,
                              mag,
                              merit))

            self.m_flux_position_port.append(res, data_dim=2)

            return merit
Ejemplo n.º 3
0
    def run(self) -> None:
        """
        Run method of the module. Calculates the SNR and FPF for a specified position in a post-
        processed image with the Student's t-test (Mawet et al. 2014). This approach assumes
        Gaussian noise but accounts for small sample statistics.

        Returns
        -------
        NoneType
            None
        """

        def _snr_optimize(arg):
            pos_x, pos_y = arg

            _, _, snr, _ = false_alarm(image=image,
                                       x_pos=pos_x,
                                       y_pos=pos_y,
                                       size=self.m_aperture,
                                       ignore=self.m_ignore)

            return -snr

        self.m_snr_out_port.del_all_data()
        self.m_snr_out_port.del_all_attributes()

        pixscale = self.m_image_in_port.get_attribute('PIXSCALE')
        self.m_aperture /= pixscale

        nimages = self.m_image_in_port.get_shape()[0]

        bounds = ((self.m_position[0]+self.m_bounds[0][0], self.m_position[0]+self.m_bounds[0][1]),
                  (self.m_position[1]+self.m_bounds[1][0], self.m_position[1]+self.m_bounds[1][1]))

        start_time = time.time()
        for j in range(nimages):
            progress(j, nimages, 'Calculating S/N and FPF...', start_time)

            image = self.m_image_in_port[j, ]
            center = center_subpixel(image)

            if self.m_optimize:
                result = minimize(fun=_snr_optimize,
                                  x0=[self.m_position[0], self.m_position[1]],
                                  method='SLSQP',
                                  bounds=bounds,
                                  tol=None,
                                  options={'ftol': self.m_tolerance})

                _, _, snr, fpf = false_alarm(image=image,
                                             x_pos=result.x[0],
                                             y_pos=result.x[1],
                                             size=self.m_aperture,
                                             ignore=self.m_ignore)

                x_pos, y_pos = result.x[0], result.x[1]

            else:
                _, _, snr, fpf = false_alarm(image=image,
                                             x_pos=self.m_position[0],
                                             y_pos=self.m_position[1],
                                             size=self.m_aperture,
                                             ignore=self.m_ignore)

                x_pos, y_pos = self.m_position[0], self.m_position[1]

            sep_ang = cartesian_to_polar(center, y_pos, x_pos)
            result = np.column_stack((x_pos, y_pos, sep_ang[0]*pixscale, sep_ang[1], snr, fpf))

            self.m_snr_out_port.append(result, data_dim=2)

        history = f'aperture [arcsec] = {self.m_aperture*pixscale:.2f}'
        self.m_snr_out_port.copy_attributes(self.m_image_in_port)
        self.m_snr_out_port.add_history('FalsePositiveModule', history)
        self.m_snr_out_port.close_port()
Ejemplo n.º 4
0
def pixel_variance(var_type: str, images: np.ndarray, parang: np.ndarray,
                   cent_size: Optional[float], edge_size: Optional[float],
                   pca_number: int, residuals: str,
                   aperture: Tuple[int, int, float], sigma: float) -> float:
    """
    Function to calculate the variance of the noise. After the PSF subtraction, images are rotated
    in opposite direction of the regular derotation, therefore dispersing any companion or disk
    signal. The noise is measured within an annulus.

    Parameters
    ----------
    var_type : str
        Variance type ('gaussian' or 'hessian').
    images : numpy.ndarray
        Input images (3D).
    parang : numpy.ndarray
        Parallactic angles.
    cent_size : float, None
        Radius of the central mask (pix). No mask is used when set to None.
    edge_size : float, None
        Outer radius (pix) beyond which pixels are masked. No outer mask is used when set to
        None.
    pca_number : int
        Number of principal components (PCs) used for the PSF subtraction.
    residuals : str
        Method for combining the residuals ('mean', 'median', 'weighted', or 'clipped').
    aperture : tuple(int, int, float)
        Aperture position (y, x) and radius (pix).
    sigma : float, None
        Standard deviation (pix) of the Gaussian kernel which is used to smooth the images.

    Returns
    -------
    float
        Variance of the pixel values. Either the variance of the pixel values ('gaussian') or
        the variance of the determinant of the Hessian ('hessian').
    """

    mask = create_mask(images.shape[-2:], (cent_size, edge_size))

    _, im_res_derot = pca_psf_subtraction(images * mask, parang, pca_number)

    res_noise = combine_residuals(residuals, im_res_derot)

    sep_ang = cartesian_to_polar(center_subpixel(res_noise), aperture[0],
                                 aperture[1])

    if var_type == 'gaussian':
        selected = select_annulus(res_noise[0, ], sep_ang[0] - aperture[2],
                                  sep_ang[0] + aperture[2])

    elif var_type == 'hessian':
        hessian_rr, hessian_rc, hessian_cc = hessian_matrix(
            image=res_noise[0, ],
            sigma=sigma,
            mode='constant',
            cval=0.,
            order='rc')

        hes_det = (hessian_rr * hessian_cc) - (hessian_rc * hessian_rc)

        selected = select_annulus(hes_det, sep_ang[0] - aperture[2],
                                  sep_ang[0] + aperture[2])

    return float(np.var(selected))
Ejemplo n.º 5
0
def merit_function(residuals: np.ndarray, merit: str,
                   aperture: Tuple[int, int, float], sigma: float) -> float:
    """
    Function to calculate the figure of merit at a given position in the image residuals.

    Parameters
    ----------
    residuals : numpy.ndarray
        Residuals of the PSF subtraction (2D).
    merit : str
        Figure of merit for the chi-square function ('hessian', 'poisson', or 'gaussian').
    aperture : tuple(int, int, float)
        Position (y, x) of the aperture center (pix) and aperture radius (pix).
    sigma : float
        Standard deviation (pix) of the Gaussian kernel which is used to smooth the residuals
        before the chi-square is calculated.

    Returns
    -------
    float
        Chi-square ('poisson' and 'gaussian') or sum of the absolute values ('hessian').
    """

    rr_grid = pixel_distance(im_shape=residuals.shape,
                             position=(aperture[0], aperture[1]))

    indices = np.where(rr_grid < aperture[2])

    if merit == 'hessian':

        # This is not the chi-square but simply the sum of the absolute values

        hessian_rr, hessian_rc, hessian_cc = hessian_matrix(image=residuals,
                                                            sigma=sigma,
                                                            mode='constant',
                                                            cval=0.,
                                                            order='rc')

        hes_det = (hessian_rr * hessian_cc) - (hessian_rc * hessian_rc)

        chi_square = np.sum(np.abs(hes_det[indices]))

    elif merit == 'poisson':

        if sigma > 0.:
            residuals = gaussian_filter(input=residuals, sigma=sigma)

        chi_square = np.sum(np.abs(residuals[indices]))

    elif merit == 'gaussian':

        # separation (pix) and position angle (deg)
        sep_ang = cartesian_to_polar(center=center_subpixel(residuals),
                                     y_pos=aperture[0],
                                     x_pos=aperture[1])

        if sigma > 0.:
            residuals = gaussian_filter(input=residuals, sigma=sigma)

        selected = select_annulus(image_in=residuals,
                                  radius_in=sep_ang[0] - aperture[2],
                                  radius_out=sep_ang[0] + aperture[2],
                                  mask_position=aperture[0:2],
                                  mask_radius=aperture[2])

        chi_square = np.sum(residuals[indices]**2) / np.var(selected)

    else:

        raise ValueError(
            'Figure of merit not recognized. Please use \'hessian\', \'poisson\' '
            'or \'gaussian\'. Previous use of \'sum\' should now be set as '
            '\'poisson\'.')

    return chi_square
Ejemplo n.º 6
0
    def run(self):
        """
        Run method of the module. Calculates the SNR and FPF for a specified position in a post-
        processed image with the Student's t-test (Mawet et al. 2014). This approach assumes
        Gaussian noise but accounts for small sample statistics.

        Returns
        -------
        NoneType
            None
        """
        def _fpf_minimize(arg):
            pos_x, pos_y = arg

            try:
                _, _, _, fpf = false_alarm(image=image,
                                           x_pos=pos_x,
                                           y_pos=pos_y,
                                           size=self.m_aperture,
                                           ignore=self.m_ignore)

            except ValueError:
                fpf = float('inf')

            return fpf

        self.m_snr_out_port.del_all_data()
        self.m_snr_out_port.del_all_attributes()

        pixscale = self.m_image_in_port.get_attribute('PIXSCALE')
        self.m_aperture /= pixscale

        nimages = self.m_image_in_port.get_shape()[0]

        start_time = time.time()
        for j in range(nimages):
            progress(j, nimages, 'Running FalsePositiveModule...', start_time)

            image = self.m_image_in_port[j, ]
            center = center_subpixel(image)

            if self.m_optimize:
                result = minimize(fun=_fpf_minimize,
                                  x0=[self.m_position[0], self.m_position[1]],
                                  method='Nelder-Mead',
                                  tol=None,
                                  options={
                                      'xatol': self.m_tolerance,
                                      'fatol': float('inf')
                                  })

                _, _, snr, fpf = false_alarm(image=image,
                                             x_pos=result.x[0],
                                             y_pos=result.x[1],
                                             size=self.m_aperture,
                                             ignore=self.m_ignore)

                x_pos, y_pos = result.x[0], result.x[1]

            else:
                _, _, snr, fpf = false_alarm(image=image,
                                             x_pos=self.m_position[0],
                                             y_pos=self.m_position[1],
                                             size=self.m_aperture,
                                             ignore=self.m_ignore)

                x_pos, y_pos = self.m_position[0], self.m_position[1]

            sep_ang = cartesian_to_polar(center, x_pos, y_pos)
            result = np.column_stack(
                (x_pos, y_pos, sep_ang[0] * pixscale, sep_ang[1], snr, fpf))

            self.m_snr_out_port.append(result, data_dim=2)

        sys.stdout.write('Running FalsePositiveModule... [DONE]\n')
        sys.stdout.flush()

        history = f'aperture [arcsec] = {self.m_aperture*pixscale:.2f}'
        self.m_snr_out_port.copy_attributes(self.m_image_in_port)
        self.m_snr_out_port.add_history('FalsePositiveModule', history)
        self.m_snr_out_port.close_port()