Esempio n. 1
0
    def run(self):
        """
        Run method of the module. Calculates the minimum, maximum, sum, mean, median, and standard
        deviation of the pixel values of each image separately. NaNs are ignored for each
        calculation. The values are calculated for either the full images or a circular
        subsection of the images.

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

        self.m_stat_out_port.del_all_data()
        self.m_stat_out_port.del_all_attributes()

        memory = self._m_config_port.get_attribute("MEMORY")
        pixscale = self.m_image_in_port.get_attribute("PIXSCALE")

        if self.m_position is not None:
            self.m_position = (
                int(self.m_position[1]),  # y position
                int(self.m_position[0]),  # x position
                self.m_position[2] / pixscale)  # radius (pix)

        nimages = self.m_image_in_port.get_shape()[0]
        im_shape = self.m_image_in_port.get_shape()[1:]

        frames = memory_frames(memory, nimages)

        for i, _ in enumerate(frames[:-1]):
            progress(i, len(frames[:-1]), "Running ImageStatisticsModule...")

            images = self.m_image_in_port[frames[i]:frames[i + 1], ]
            images = np.reshape(images,
                                (images.shape[0], im_shape[0] * im_shape[1]))

            if self.m_position is not None:
                rr_grid = pixel_distance(im_shape, self.m_position)
                indices = np.where(rr_grid <= self.m_position[2])[0]
                images = images[:, indices]

            nmin = np.nanmin(images, axis=1)
            nmax = np.nanmax(images, axis=1)
            nsum = np.nansum(images, axis=1)
            mean = np.nanmean(images, axis=1)
            median = np.nanmedian(images, axis=1)
            std = np.nanstd(images, axis=1)

            result = np.column_stack((nmin, nmax, nsum, mean, median, std))
            self.m_stat_out_port.append(result)

        sys.stdout.write("Running ImageStatisticsModule... [DONE]\n")
        sys.stdout.flush()

        history = "number of images = " + str(nimages)
        self.m_stat_out_port.copy_attributes(self.m_image_in_port)
        self.m_stat_out_port.add_history("ImageStatisticsModule", history)
        self.m_stat_out_port.close_port()
Esempio n. 2
0
    def run(self) -> None:
        """
        Run method of the module. Applies a frame selection on the derotated residuals from the
        PSF subtraction. The pixels within an annulus (e.g. at the separation of an expected
        planet) are selected and the standard deviation is calculated. The chosen percentage
        of images with the lowest standard deviation are stored as output.

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

        pixscale = self.m_image_in_port.get_attribute('PIXSCALE')
        nimages = self.m_image_in_port.get_shape()[0]
        npix = self.m_image_in_port.get_shape()[-1]

        rr_grid, _, _ = pixel_distance((npix, npix), position=None)

        pixel_select = np.where((rr_grid > self.m_annulus_radii[0] / pixscale)
                                &
                                (rr_grid < self.m_annulus_radii[1] / pixscale))

        start_time = time.time()
        phot_annulus = np.zeros(nimages)

        for i in range(nimages):
            progress(i, nimages, 'Aperture photometry...', start_time)

            phot_annulus[i] = np.sum(
                np.abs(self.m_image_in_port[i][pixel_select]))

        print(
            f'Minimum, maximum = {np.amin(phot_annulus):.2f}, {np.amax(phot_annulus):.2f}'
        )
        print(
            f'Mean, median = {np.nanmean(phot_annulus):.2f}, {np.nanmedian(phot_annulus):.2f}'
        )
        print(f'Standard deviation = {np.nanstd(phot_annulus):.2f}')

        n_select = int(nimages * self.m_percentage / 100.)
        index_del = np.argsort(phot_annulus)[n_select:]

        write_selected_data(memory=self._m_config_port.get_attribute('MEMORY'),
                            indices=index_del,
                            image_in_port=self.m_image_in_port,
                            selected_out_port=self.m_selected_out_port,
                            removed_out_port=self.m_removed_out_port)

        write_selected_attributes(indices=index_del,
                                  image_in_port=self.m_image_in_port,
                                  selected_out_port=self.m_selected_out_port,
                                  removed_out_port=self.m_removed_out_port,
                                  module_type='ResidualSelectionModule',
                                  history=f'frames removed = {index_del.size}')

        self.m_image_in_port.close_port()
Esempio n. 3
0
    def run(self) -> None:
        """
        Run method of the module. Calculates the minimum, maximum, sum, mean, median, and standard
        deviation of the pixel values of each image separately. NaNs are ignored for each
        calculation. The values are calculated for either the full images or a circular
        subsection of the images.

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

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

        nimages = self.m_image_in_port.get_shape()[0]
        im_shape = self.m_image_in_port.get_shape()[1:]

        if self.m_position is None:
            indices = None

        else:
            if self.m_position[0] is None and self.m_position[1] is None:
                center = center_pixel(self.m_image_in_port[0, ])

                self.m_position = (
                    center[0],  # y position
                    center[1],  # x position
                    self.m_position[2] / pixscale)  # radius (pix)

            else:
                self.m_position = (
                    int(self.m_position[1]),  # y position
                    int(self.m_position[0]),  # x position
                    self.m_position[2] / pixscale)  # radius (pix)

            rr_grid, _, _ = pixel_distance(im_shape,
                                           position=self.m_position[0:2])
            rr_reshape = np.reshape(rr_grid,
                                    (rr_grid.shape[0] * rr_grid.shape[1]))
            indices = np.where(rr_reshape <= self.m_position[2])[0]

        self.apply_function_to_images(image_stat,
                                      self.m_image_in_port,
                                      self.m_stat_out_port,
                                      'Calculating image statistics',
                                      func_args=(indices, ))

        history = f'number of images = {nimages}'
        self.m_stat_out_port.copy_attributes(self.m_image_in_port)
        self.m_stat_out_port.add_history('ImageStatisticsModule', history)
        self.m_stat_out_port.close_port()
Esempio n. 4
0
def merit_function(residuals: np.ndarray, merit: str, aperture: Tuple[int, int,
                                                                      float],
                   sigma: float, var_noise: Optional[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.
    var_noise : float, None
        Variance of the noise which is required when `merit` is set to 'gaussian' or 'hessian'.

    Returns
    -------
    float
        Chi-square value.
    """

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

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

    if merit == 'hessian':

        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(hes_det[indices]**2) / var_noise

    elif merit == 'poisson':

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

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

    elif merit == 'gaussian':

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

    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
Esempio 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
Esempio n. 6
0
    def run(self) -> None:
        """
        Run method of the module. Uses a non-linear least squares (Levenberg-Marquardt) method
        to fit the the individual images or the mean of all images with a 2D Gaussian or Moffat
        function. The best-fit results and errors are stored and contain zeros in case the
        algorithm could not converge. The ``fit_out_tag`` can be used as argument of ``shift_xy``
        when running the :class:`~pynpoint.processing.centering.ShiftImagesModule`.

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

        memory = self._m_config_port.get_attribute('MEMORY')
        cpu = self._m_config_port.get_attribute('CPU')
        pixscale = self.m_image_in_port.get_attribute('PIXSCALE')

        if cpu > 1 and self.m_mask_out_port is not None:
            warnings.warn('The mask_out_port can only be used if CPU=1. No data will be '
                          'stored to this output port.')

            del self._m_output_ports[self.m_mask_out_port.tag]
            self.m_mask_out_port = None

        if self.m_mask_radii[0] is None:
            # Convert from arcsec to pixels and change None to 0
            self.m_mask_radii = (0., self.m_mask_radii[1]/pixscale)

        else:
            # Convert from arcsec to pixels
            self.m_mask_radii = (self.m_mask_radii[0]/pixscale, self.m_mask_radii[1]/pixscale)

        if self.m_filter_size:
            # Convert from arcsec to pixels
            self.m_filter_size /= pixscale

        _, xx_grid, yy_grid = pixel_distance(self.m_image_in_port.get_shape()[-2:], position=None)

        rr_ap = subpixel_distance(self.m_image_in_port.get_shape()[-2:],
                                  position=(self.m_guess[1], self.m_guess[0]),
                                  shift_center=False)  # (y, x)

        nimages = self.m_image_in_port.get_shape()[0]
        frames = memory_frames(memory, nimages)

        if self.m_method == 'full':

            self.apply_function_to_images(fit_2d_function,
                                          self.m_image_in_port,
                                          self.m_fit_out_port,
                                          'Fitting the stellar PSF',
                                          func_args=(self.m_mask_radii,
                                                     self.m_sign,
                                                     self.m_model,
                                                     self.m_filter_size,
                                                     self.m_guess,
                                                     self.m_mask_out_port,
                                                     xx_grid,
                                                     yy_grid,
                                                     rr_ap,
                                                     pixscale))

        elif self.m_method == 'mean':
            print('Fitting the stellar PSF...', end='')

            im_mean = np.zeros(self.m_image_in_port.get_shape()[1:3])

            for i, _ in enumerate(frames[:-1]):
                im_mean += np.sum(self.m_image_in_port[frames[i]:frames[i+1], ], axis=0)

            best_fit = fit_2d_function(im_mean/float(nimages),
                                       0,
                                       self.m_mask_radii,
                                       self.m_sign,
                                       self.m_model,
                                       self.m_filter_size,
                                       self.m_guess,
                                       self.m_mask_out_port,
                                       xx_grid,
                                       yy_grid,
                                       rr_ap,
                                       pixscale)

            best_fit = best_fit[np.newaxis, ...]
            best_fit = np.repeat(best_fit, nimages, axis=0)

            self.m_fit_out_port.set_all(best_fit, data_dim=2)

            print(' [DONE]')

        history = f'model = {self.m_model}'

        self.m_fit_out_port.copy_attributes(self.m_image_in_port)
        self.m_fit_out_port.add_history('FitCenterModule', history)

        if self.m_mask_out_port:
            self.m_mask_out_port.copy_attributes(self.m_image_in_port)
            self.m_mask_out_port.add_history('FitCenterModule', history)

        self.m_fit_out_port.close_port()
Esempio n. 7
0
    def run(self) -> None:
        """
        Run method of the module. Calculates the minimum, maximum, sum, mean, median, and standard
        deviation of the pixel values of each image separately. NaNs are ignored for each
        calculation. The values are calculated for either the full images or a circular
        subsection of the images.

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

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

        nimages = self.m_image_in_port.get_shape()[0]
        im_shape = self.m_image_in_port.get_shape()[1:]

        if self.m_position is None:
            indices = None

        else:
            if self.m_position[0] is None and self.m_position[1] is None:
                center = center_pixel(self.m_image_in_port[0, ])

                self.m_position = (center[0],  # y position
                                   center[1],  # x position
                                   self.m_position[2]/pixscale)  # radius (pix)

            else:
                self.m_position = (int(self.m_position[1]),  # y position
                                   int(self.m_position[0]),  # x position
                                   self.m_position[2]/pixscale)  # radius (pix)

            rr_grid = pixel_distance(im_shape, self.m_position[0:2])
            rr_reshape = np.reshape(rr_grid, (rr_grid.shape[0]*rr_grid.shape[1]))
            indices = np.where(rr_reshape <= self.m_position[2])[0]

        @typechecked
        def _image_stat(image_in: np.ndarray,
                        indices: Optional[np.ndarray]) -> np.ndarray:

            if indices is None:
                image_select = np.copy(image_in)

            else:
                image_reshape = np.reshape(image_in, (image_in.shape[0]*image_in.shape[1]))
                image_select = image_reshape[indices]

            nmin = np.nanmin(image_select)
            nmax = np.nanmax(image_select)
            nsum = np.nansum(image_select)
            mean = np.nanmean(image_select)
            median = np.nanmedian(image_select)
            std = np.nanstd(image_select)

            return np.asarray([nmin, nmax, nsum, mean, median, std])

        self.apply_function_to_images(_image_stat,
                                      self.m_image_in_port,
                                      self.m_stat_out_port,
                                      'Calculating image statistics',
                                      func_args=(indices, ))

        history = f'number of images = {nimages}'
        self.m_stat_out_port.copy_attributes(self.m_image_in_port)
        self.m_stat_out_port.add_history('ImageStatisticsModule', history)
        self.m_stat_out_port.close_port()