Beispiel #1
0
def radial_profile(light_grid, x_grid, y_grid, center_x=0, center_y=0, n=None):
    """
    computes radial profile

    :param light_grid: array of surface brightness
    :param x_grid: x-axis coordinates
    :param y_grid: y-axis coordinates
    :param center_x: center of light
    :param center_y: center of light
    :param n: number of discrete steps
    :return: I(r), r with r in units of the coordinate grid
    """
    r_max = np.max(np.sqrt((x_grid - center_x)**2 + (y_grid - center_y)**2))
    if n is None:
        n = int(np.sqrt(len(x_grid)))
    I_r = np.zeros(n)
    I_enclosed = 0
    r = np.linspace(1. / n * r_max, r_max, n)
    for i, r_i in enumerate(r):
        mask = mask_util.mask_azimuthal(x_grid, y_grid, center_x, center_y,
                                        r_i)
        flux_enclosed = np.sum(np.array(light_grid) * mask)
        I_r[i] = flux_enclosed - I_enclosed
        I_enclosed = flux_enclosed
    return I_r, r
Beispiel #2
0
    def mass_fraction_within_radius(self,
                                    kwargs_lens,
                                    center_x,
                                    center_y,
                                    theta_E,
                                    numPix=100):
        """
        computes the mean convergence of all the different lens model components within a spherical aperture

        :param kwargs_lens: lens model keyword argument list
        :param center_x: center of the aperture
        :param center_y: center of the aperture
        :param theta_E: radius of aperture
        :return: list of average convergences for all the model components
        """
        x_grid, y_grid = util.make_grid(numPix=numPix,
                                        deltapix=2. * theta_E / numPix)
        x_grid += center_x
        y_grid += center_y
        mask = mask_util.mask_azimuthal(x_grid, y_grid, center_x, center_y,
                                        theta_E)
        kappa_list = []
        for i in range(len(kwargs_lens)):
            kappa = self._lens_model.kappa(x_grid, y_grid, kwargs_lens, k=i)
            kappa_mean = np.sum(kappa * mask) / np.sum(mask)
            kappa_list.append(kappa_mean)
        return kappa_list
Beispiel #3
0
    def error_map_estimate(self, kernel, star_cutout_list, amp, x_pos, y_pos, error_map_radius=None):
        """
        provides a psf_error_map based on the goodness of fit of the given PSF kernel on the point source cutouts,
        their estimated amplitudes and positions

        :param kernel: PSF kernel
        :param star_cutout_list: list of 2d arrays of cutouts of the point sources with all other model components subtracted
        :param amp: list of amplitudes of the estimated PSF kernel
        :param x_pos: pixel position (in original data unit, not in cutout) of the point sources (same order as amp and star cutouts)
        :param y_pos: pixel position (in original data unit, not in cutout) of the point sources (same order as amp and star cutouts)
        :param error_map_radius: float, radius (in arc seconds) of the outermost error in the PSF estimate (e.g. to avoid double counting of overlapping PSF erros)
        :return: relative uncertainty in the psf model (in quadrature) per pixel based on residuals achieved in the image
        """
        error_map_list = np.zeros((len(star_cutout_list), len(kernel), len(kernel)))
        for i, star in enumerate(star_cutout_list):
            x, y, amp_i = x_pos[i], y_pos[i], amp[i]
            # shift kernel
            x_int = int(round(x))
            y_int = int(round(y))
            shift_x = x_int - x
            shift_y = y_int - y
            kernel_shifted = interp.shift(kernel, [-shift_y, -shift_x], order=1)
            # multiply kernel with amplitude
            model = kernel_shifted * amp_i
            # compute residuals
            residual = np.abs(star - model)
            # subtract background and Poisson noise residuals
            C_D_cutout = kernel_util.cutout_source(x_int, y_int, self._image_model_class.Data.C_D, len(star), shift=False)
            mask = kernel_util.cutout_source(x_int, y_int, self._image_model_class.likelihood_mask, len(star), shift=False)
            residual -= np.sqrt(C_D_cutout)
            residual[residual < 0] = 0
            # estimate relative error per star
            residual /= amp_i
            error_map_list[i, :, :] = residual**2*mask
        # take median absolute error for each pixel
        error_map = np.median(error_map_list, axis=0)
        error_map[kernel > 0] /= kernel[kernel > 0]**2
        error_map = np.nan_to_num(error_map)
        error_map[error_map > 1] = 1  # cap on error to be the same

        # mask the error map outside a certain radius (can avoid double counting of errors when map is overlapping
        if error_map_radius is not None:
            pixel_scale = self._image_model_class.Data.pixel_width
            x_grid, y_grid = util.make_grid(numPix=len(error_map), deltapix=pixel_scale)
            mask = mask_util.mask_azimuthal(x_grid, y_grid, center_x=0, center_y=0, r=error_map_radius)
            error_map *= util.array2image(mask)
        return error_map
Beispiel #4
0
    def mask_point_source(x_pos, y_pos, x_grid, y_grid, radius, i=0):
        """

        :param x_pos: x-position of list of point sources
        :param y_pos: y-position of list of point sources
        :param x_grid: x-coordinates of grid
        :param y_grid: y-coordinates of grid
        :param i: index of point source not to mask out
        :param radius: radius to mask out other point sources
        :return: a mask of the size of the image with cutouts around the position
        """
        mask = np.ones_like(x_grid)
        for k in range(len(x_pos)):
            if k != i:
                mask_point = 1 - mask_util.mask_azimuthal(x_grid, y_grid, x_pos[k], y_pos[k], radius)
                mask *= mask_point
        return util.array2image(mask)
Beispiel #5
0
def moments(I_xy_input, x, y):
    """
    compute quadrupole moments from a light distribution

    :param I_xy_input: light distribution
    :param x: x-coordinates of I_xy
    :param y: y-coordinates of I_xy
    :return: Q_xx, Q_xy, Q_yy
    """
    I_xy = copy.deepcopy(I_xy_input)
    background = np.minimum(0, np.min(I_xy))
    I_xy -= background
    x_ = np.sum(I_xy * x)
    y_ = np.sum(I_xy * y)
    r = (np.max(x) - np.min(x)) / 3.
    mask = mask_util.mask_azimuthal(x, y, center_x=x_, center_y=y_, r=r)
    Q_xx = np.sum(I_xy * mask * (x - x_)**2)
    Q_xy = np.sum(I_xy * mask * (x - x_) * (y - y_))
    Q_yy = np.sum(I_xy * mask * (y - y_)**2)
    return Q_xx, Q_xy, Q_yy, background / np.mean(I_xy)
Beispiel #6
0
def half_light_radius(lens_light, x_grid, y_grid, center_x=0, center_y=0):
    """

    :param lens_light: array of surface brightness
    :param x_grid: x-axis coordinates
    :param y_grid: y-axis coordinates
    :param center_x: center of light
    :param center_y: center of light
    :return:
    """
    lens_light[lens_light < 0] = 0
    total_flux_2 = np.sum(lens_light) / 2.
    r_max = np.max(np.sqrt((x_grid - center_x)**2 + (y_grid - center_y)**2))
    for i in range(1000):
        r = i / 500. * r_max
        mask = mask_util.mask_azimuthal(x_grid, y_grid, center_x, center_y, r)
        flux_enclosed = np.sum(np.array(lens_light) * mask)
        if flux_enclosed > total_flux_2:
            return r
    return -1
Beispiel #7
0
    def error_map_estimate_new(self,
                               psf_kernel,
                               psf_kernel_list,
                               ra_image,
                               dec_image,
                               point_amp,
                               supersampling_factor,
                               error_map_radius=None):
        """
        relative uncertainty in the psf model (in quadrature) per pixel based on residuals achieved in the image

        :param psf_kernel: PSF kernel (super-sampled)
        :param psf_kernel_list: list of individual best PSF kernel estimates
        :param ra_image: image positions in angles
        :param dec_image: image positions in angles
        :param point_amp: image amplitude
        :param supersampling_factor: super-sampling factor
        :param error_map_radius: radius (in angle) to cut the error map
        :return: psf error map such that square of the uncertainty gets boosted by error_map * (psf * amp)**2
        """
        kernel_low = kernel_util.degrade_kernel(psf_kernel,
                                                supersampling_factor)
        error_map_list = np.zeros(
            (len(psf_kernel_list), len(kernel_low), len(kernel_low)))
        x_pos, y_pos = self._image_model_class.Data.map_coord2pix(
            ra_image, dec_image)

        for i, psf_kernel_i in enumerate(psf_kernel_list):
            kernel_low_i = kernel_util.degrade_kernel(psf_kernel_i,
                                                      supersampling_factor)

            x, y, amp_i = x_pos[i], y_pos[i], point_amp[i]
            x_int = int(round(x))
            y_int = int(round(y))

            C_D_cutout = kernel_util.cutout_source(
                x_int,
                y_int,
                self._image_model_class.Data.C_D,
                len(kernel_low_i),
                shift=False)
            residuals_i = np.abs(kernel_low - kernel_low_i)
            residuals_i -= np.sqrt(C_D_cutout) / amp_i
            residuals_i[residuals_i < 0] = 0
            error_map_list[i, :, :] = residuals_i**2

        error_map = np.median(error_map_list, axis=0)
        error_map[kernel_low > 0] /= kernel_low[kernel_low > 0]**2
        error_map = np.nan_to_num(error_map)
        error_map[error_map > 1] = 1  # cap on error to be the same

        # mask the error map outside a certain radius (can avoid double counting of errors when map is overlapping
        if error_map_radius is not None:
            pixel_scale = self._image_model_class.Data.pixel_width
            x_grid, y_grid = util.make_grid(numPix=len(error_map),
                                            deltapix=pixel_scale)
            mask = mask_util.mask_azimuthal(x_grid,
                                            y_grid,
                                            center_x=0,
                                            center_y=0,
                                            r=error_map_radius)
            error_map *= util.array2image(mask)
        return error_map