Esempio n. 1
0
    def profile_slope(self,
                      kwargs_lens,
                      radius,
                      center_x=None,
                      center_y=None,
                      model_list_bool=None,
                      num_points=10):
        """
        computes the logarithmic power-law slope of a profile. ATTENTION: this is not an observable!

        :param kwargs_lens: lens model keyword argument list
        :param radius: radius from the center where to compute the logarithmic slope (angular units
        :param model_list_bool: bool list, indicate which part of the model to consider
        :param num_points: number of estimates around the Einstein radius
        :return: logarithmic power-law slope
        """
        center_x, center_y = analysis_util.profile_center(
            kwargs_lens, center_x, center_y)
        x, y = util.points_on_circle(radius, num_points)
        dr = 0.01
        x_dr, y_dr = util.points_on_circle(radius + dr, num_points)

        alpha_E_x_i, alpha_E_y_i = self._lens_model.alpha(center_x + x,
                                                          center_y + y,
                                                          kwargs_lens,
                                                          k=model_list_bool)
        alpha_E_r = np.sqrt(alpha_E_x_i**2 + alpha_E_y_i**2)
        alpha_E_dr_x_i, alpha_E_dr_y_i = self._lens_model.alpha(
            center_x + x_dr, center_y + y_dr, kwargs_lens, k=model_list_bool)
        alpha_E_dr = np.sqrt(alpha_E_dr_x_i**2 + alpha_E_dr_y_i**2)
        slope = np.mean(
            np.log(alpha_E_dr / alpha_E_r) / np.log((radius + dr) / radius))
        gamma = -slope + 2
        return gamma
Esempio n. 2
0
    def profile_slope(self, kwargs_lens_list, lens_model_internal_bool=None, num_points=10):
        """
        computes the logarithmic power-law slope of a profile

        :param kwargs_lens_list: lens model keyword argument list
        :param lens_model_internal_bool: bool list, indicate which part of the model to consider
        :param num_points: number of estimates around the Einstein radius
        :return:
        """
        theta_E = self.effective_einstein_radius(kwargs_lens_list)
        x0 = kwargs_lens_list[0]['center_x']
        y0 = kwargs_lens_list[0]['center_y']
        x, y = util.points_on_circle(theta_E, num_points)
        dr = 0.01
        x_dr, y_dr = util.points_on_circle(theta_E + dr, num_points)
        if lens_model_internal_bool is None:
            lens_model_internal_bool = [True]*len(kwargs_lens_list)

        alpha_E_x_i, alpha_E_y_i = self._lensModel.alpha(x0 + x, y0 + y, kwargs_lens_list, k=lens_model_internal_bool)
        alpha_E_r = np.sqrt(alpha_E_x_i**2 + alpha_E_y_i**2)
        alpha_E_dr_x_i, alpha_E_dr_y_i = self._lensModel.alpha(x0 + x_dr, y0 + y_dr, kwargs_lens_list,
                                                               k=lens_model_internal_bool)
        alpha_E_dr = np.sqrt(alpha_E_dr_x_i ** 2 + alpha_E_dr_y_i ** 2)
        slope = np.mean(np.log(alpha_E_dr / alpha_E_r) / np.log((theta_E + dr) / theta_E))
        gamma = -slope + 2
        return gamma
Esempio n. 3
0
def test_points_on_circle():
    radius = 1
    points = 8
    ra, dec = util.points_on_circle(radius, points, connect_ends=True)
    assert ra[0] == 1
    assert dec[0] == 0

    ra_, dec_ = util.points_on_circle(radius, points - 1, connect_ends=False)
    npt.assert_almost_equal(ra[:-1], ra_, decimal=8)
    npt.assert_almost_equal(dec[:-1], dec_, decimal=8)
Esempio n. 4
0
    def radial_light_profile(self,
                             r_list,
                             kwargs_light,
                             center_x=None,
                             center_y=None,
                             model_bool_list=None):
        """

        :param r_list: list of radii to compute the spherically averaged lens light profile
        :param center_x: center of the profile
        :param center_y: center of the profile
        :param kwargs_light: lens light parameter keyword argument list
        :param model_bool_list: bool list or None, indicating which profiles to sum over
        :return: flux amplitudes at r_list radii spherically averaged
        """
        center_x, center_y = analysis_util.profile_center(
            kwargs_light, center_x, center_y)
        f_list = []
        for r in r_list:
            x, y = util.points_on_circle(r, num_points=20)
            f_r = self._light_model.surface_brightness(
                x + center_x,
                y + center_y,
                kwargs_list=kwargs_light,
                k=model_bool_list)
            f_list.append(np.average(f_r))
        return f_list
Esempio n. 5
0
    def mst_invariant_differential(self,
                                   kwargs_lens,
                                   radius,
                                   center_x=None,
                                   center_y=None,
                                   model_list_bool=None,
                                   num_points=10):
        """
        Average of the radial stretch differential in radial direction, divided by the radial stretch factor.

        .. math::
            \\xi = \\frac{\\partial \\lambda_{\\rm rad}}{\\partial r} \\frac{1}{\\lambda_{\\rm rad}}

        This quantity is invariant under the MST.
        The specific definition is provided by Birrer 2021. Equivalent (proportional) definitions are provided by e.g.
        Kochanek 2020, Sonnenfeld 2018.

        :param kwargs_lens: lens model keyword argument list
        :param radius: radius from the center where to compute the MST invariant differential
        :param center_x: center position
        :param center_y: center position
        :param model_list_bool: indicate which part of the model to consider
        :param num_points: number of estimates around the radius
        :return: xi
        """
        center_x, center_y = analysis_util.profile_center(
            kwargs_lens, center_x, center_y)
        x, y = util.points_on_circle(radius, num_points)
        ext = LensModelExtensions(lensModel=self._lens_model)
        lambda_rad, lambda_tan, orientation_angle, dlambda_tan_dtan, dlambda_tan_drad, dlambda_rad_drad, dlambda_rad_dtan, dphi_tan_dtan, dphi_tan_drad, dphi_rad_drad, dphi_rad_dtan = ext.radial_tangential_differentials(
            x, y, kwargs_lens, center_x=center_x, center_y=center_y)
        xi = np.mean(dlambda_rad_drad / lambda_rad)
        return xi
Esempio n. 6
0
def test_area():
    r = 1
    x_, y_ = util.points_on_circle(radius=r,
                                   connect_ends=True,
                                   num_points=1000)
    vs = np.dstack([x_, y_])[0]
    a = util.area(vs)
    npt.assert_almost_equal(a, np.pi * r**2, decimal=3)
    def curved_arc_finite_area(self, x, y, kwargs_lens, dr):
        """
        computes an estimated curved arc over a finite extent mimicking the appearance of a finite source with radius dr

        :param x: x-position (float)
        :param y: y-position (float)
        :param kwargs_lens: lens model keyword argument list
        :param dr: radius of finite source
        :return: keyword arguments of curved arc
        """

        # estimate curvature centroid as the median around the circle

        # make circle of points around position of interest
        x_c, y_c = util.points_on_circle(radius=dr, num_points=20, connect_ends=False)

        c_x_list, c_y_list = [], []
        # loop through curved arc estimate and compute curvature centroid
        for x_, y_ in zip(x_c, y_c):
            kwargs_arc_ = self.curved_arc_estimate(x_, y_, kwargs_lens)
            direction = kwargs_arc_['direction']
            curvature = kwargs_arc_['curvature']
            center_x = x_ - np.cos(direction) / curvature
            center_y = y_ - np.sin(direction) / curvature
            c_x_list.append(center_x)
            c_y_list.append(center_y)
        center_x, center_y = np.median(c_x_list), np.median(c_y_list)

        # compute curvature and direction to the average centroid from the position of interest
        r = np.sqrt((x - center_x) ** 2 + (y - center_y)**2)
        curvature = 1 / r
        direction = np.arctan2(y - center_y, x - center_x)

        # compute average radial stretch as the inverse difference in the source position
        x_r = x + np.cos(direction) * dr
        y_r = y + np.sin(direction) * dr
        x_r_ = x - np.cos(direction) * dr
        y_r_ = y - np.sin(direction) * dr

        xs_r, ys_r = self._lensModel.ray_shooting(x_r, y_r, kwargs_lens)
        xs_r_, ys_r_ = self._lensModel.ray_shooting(x_r_, y_r_, kwargs_lens)
        ds = np.sqrt((xs_r - xs_r_)**2 + (ys_r - ys_r_)**2)
        radial_stretch = (2 * dr) / ds

        # compute average tangential stretch as the inverse difference in the sosurce position
        x_t = x - np.sin(direction) * dr
        y_t = y + np.cos(direction) * dr
        x_t_ = x + np.sin(direction) * dr
        y_t_ = y - np.cos(direction) * dr

        xs_t, ys_t = self._lensModel.ray_shooting(x_t, y_t, kwargs_lens)
        xs_t_, ys_t_ = self._lensModel.ray_shooting(x_t_, y_t_, kwargs_lens)
        ds = np.sqrt((xs_t - xs_t_) ** 2 + (ys_t - ys_t_) ** 2)
        tangential_stretch = (2 * dr) / ds
        kwargs_arc = {'direction': direction, 'radial_stretch': radial_stretch,
                      'tangential_stretch': tangential_stretch, 'center_x': x, 'center_y': y,
                      'curvature': curvature}
        return kwargs_arc
Esempio n. 8
0
def plot_arc(ax,
             tangential_stretch,
             radial_stretch,
             curvature,
             direction,
             center_x,
             center_y,
             stretch_scale=0.1):
    """

    :param ax:
    :param tangential_stretch: float, stretch of intrinsic source in tangential direction
    :param radial_stretch: float, stretch of intrinsic source in radial direction
    :param curvature: 1/curvature radius
    :param direction: float, angle in radian
    :param center_x: center of source in image plane
    :param center_y: center of source in image plane
    :return:
    """
    # plot line to centroid
    center_x_spp, center_y_spp = center_deflector(curvature, direction,
                                                  center_x, center_y)
    ax.plot([center_x, center_x_spp], [center_y, center_y_spp],
            'k--',
            alpha=0.5)
    ax.plot([center_x_spp], [center_y_spp], 'k*', alpha=0.5)

    # plot radial and tangential stretch to scale

    x_r = np.cos(direction) * radial_stretch * stretch_scale
    y_r = np.sin(direction) * radial_stretch * stretch_scale
    ax.plot([center_x - x_r, center_x + x_r], [center_y - y_r, center_y + y_r],
            'k-')

    # plot curved tangential stretch
    #x_t = np.sin(direction) * tangential_stretch / 2 * stretch_scale
    #y_t = -np.cos(direction) * tangential_stretch / 2 * stretch_scale

    # compute angle of size of the tangential stretch
    r = 1. / curvature
    d_phi = tangential_stretch * stretch_scale / r

    # linearly interpolate angle around center
    phi = np.linspace(-1, 1, 50) * d_phi + direction
    # plot points on circle
    x_curve = r * np.cos(phi) + center_x_spp
    y_curve = r * np.sin(phi) + center_y_spp
    ax.plot(x_curve, y_curve, 'k-')

    # make round circle with start point to end to close the circle
    r_c, t_c = util.points_on_circle(radius=stretch_scale, num_points=50)
    r_c = radial_stretch * r_c + r
    phi_c = t_c * tangential_stretch / r_c + direction
    x_c = r_c * np.cos(phi_c) + center_x_spp
    y_c = r_c * np.sin(phi_c) + center_y_spp
    ax.plot(x_c, y_c, 'k--')
Esempio n. 9
0
def plot_arc(ax, tangential_stretch, radial_stretch, curvature, direction, center_x, center_y, stretch_scale=0.1,
             with_centroid=True, linewidth=1, color='k', dtan_dtan=0):
    """

    :param ax:
    :param tangential_stretch: float, stretch of intrinsic source in tangential direction
    :param radial_stretch: float, stretch of intrinsic source in radial direction
    :param curvature: 1/curvature radius
    :param direction: float, angle in radian
    :param center_x: center of source in image plane
    :param center_y: center of source in image plane
    :param with_centroid: plots the center of the curvature radius
    :param stretch_scale: float, relative scale of banana to the tangential and radial stretches (effectively intrinsic source size)
    :return:
    """
    # plot line to centroid
    center_x_spp, center_y_spp = center_deflector(curvature, direction, center_x, center_y)
    if with_centroid:
        ax.plot([center_x, center_x_spp], [center_y, center_y_spp], '--', color=color, alpha=0.5, linewidth=linewidth)
        ax.plot([center_x_spp], [center_y_spp], '*', color=color, alpha=0.5, linewidth=linewidth)

    # plot radial stretch to scale

    x_r = np.cos(direction) * radial_stretch * stretch_scale
    y_r = np.sin(direction) * radial_stretch * stretch_scale
    ax.plot([center_x - x_r, center_x + x_r], [center_y - y_r, center_y + y_r], '--', color=color, linewidth=linewidth)

    # plot curved tangential stretch
    #x_t = np.sin(direction) * tangential_stretch / 2 * stretch_scale
    #y_t = -np.cos(direction) * tangential_stretch / 2 * stretch_scale

    # compute angle of size of the tangential stretch
    r = 1. / curvature

    # make sure tangential stretch * stretch_scale is not larger than r * 2pi such that the full circle is only plotted once
    tangential_stretch_ = min(tangential_stretch, np.pi * r / stretch_scale)

    d_phi = tangential_stretch_ * stretch_scale / r

    # linearly interpolate angle around center
    phi = np.linspace(-1, 1, 50) * d_phi + direction
    # plot points on circle
    x_curve = r * np.cos(phi) + center_x_spp
    y_curve = r * np.sin(phi) + center_y_spp
    ax.plot(x_curve, y_curve, '--', color=color, linewidth=linewidth)

    # make round circle with start point to end to close the circle
    r_c, t_c = util.points_on_circle(radius=stretch_scale, num_points=200)
    r_c = radial_stretch * r_c + r
    phi_c = t_c * tangential_stretch_ / r_c + direction
    x_c = r_c * np.cos(phi_c) + center_x_spp
    y_c = r_c * np.sin(phi_c) + center_y_spp
    ax.plot(x_c, y_c, '-', color=color, linewidth=linewidth)
Esempio n. 10
0
    def position_size_estimate(self, ra_pos, dec_pos, kwargs_lens, kwargs_else, delta, scale=1):
        """
        estimate the magnification at the positions and define resolution limit

        :param ra_pos:
        :param dec_pos:
        :param kwargs_lens:
        :param kwargs_else:
        :return:
        """
        x, y = self.LensModel.ray_shooting(ra_pos, dec_pos, kwargs_else, **kwargs_lens)
        d_x, d_y = util.points_on_circle(delta*2, 10)
        x_s, y_s = self.LensModel.ray_shooting(ra_pos + d_x, dec_pos + d_y, kwargs_else, **kwargs_lens)
        x_m = np.mean(x_s)
        y_m = np.mean(y_s)
        r_m = np.sqrt((x_s - x_m) ** 2 + (y_s - y_m) ** 2)
        r_min = np.sqrt(r_m.min(axis=0)*r_m.max(axis=0))/2 * scale
        return x, y, r_min
Esempio n. 11
0
def test_points_on_circle():
    radius = 1
    points = 8
    ra, dec = util.points_on_circle(radius, points)
    assert ra[0] == 1
    assert dec[0] == 0