Exemplo n.º 1
0
def test_findOverlap():
    x_mins = [0, 1, 0]
    y_mins = [1, 2, 1]
    deltapix = 0.5
    x_mins, y_mins = image_util.findOverlap(x_mins, y_mins, deltapix)
    print(x_mins, y_mins)
    assert x_mins[0] == 0
    assert y_mins[0] == 1
    assert len(x_mins) == 2
    def image_position_stochastic(self,
                                  source_x,
                                  source_y,
                                  kwargs_lens,
                                  search_window=10,
                                  precision_limit=10**(-10),
                                  arrival_time_sort=True,
                                  x_center=0,
                                  y_center=0,
                                  num_random=1000):
        """
        Solves the lens equation stochastically with the scipy minimization routine on the quadratic distance between
        the backwards ray-shooted proposed image position and the source position.
        Credits to Giulia Pagano

        :param source_x: source position
        :param source_y: source position
        :param kwargs_lens: lens model list of keyword arguments
        :param search_window: angular size of search window
        :param precision_limit: limit required on the precision in the source plane
        :param arrival_time_sort: bool, if True sorts according to arrival time
        :param x_center: center of search window
        :param y_center: center of search window
        :param num_random: number of random starting points of the non-linear solver in the search window
        :param verbose: bool, if True, prints performance information
        :return: x_image, y_image
        """
        kwargs_lens = self._static_lens_settings(kwargs_lens)

        x_solve, y_solve = [], []
        for i in range(num_random):
            x_init = np.random.uniform(-search_window / 2.,
                                       search_window / 2) + x_center
            y_init = np.random.uniform(-search_window / 2.,
                                       search_window / 2) + y_center
            xinitial = np.array([x_init, y_init])
            result = minimize(self._root,
                              xinitial,
                              args=(kwargs_lens, source_x, source_y),
                              tol=precision_limit**2,
                              method='Nelder-Mead')
            if self._root(result.x, kwargs_lens, source_x,
                          source_y) < precision_limit**2:
                x_solve.append(result.x[0])
                y_solve.append(result.x[1])

        x_mins, y_mins = image_util.findOverlap(x_solve, y_solve,
                                                precision_limit)
        if arrival_time_sort is True:
            x_mins, y_mins = self.sort_arrival_times(x_mins, y_mins,
                                                     kwargs_lens)
        self._make_dynamic()
        return x_mins, y_mins
Exemplo n.º 3
0
    def image_position_from_source(self,
                                   sourcePos_x,
                                   sourcePos_y,
                                   kwargs_lens,
                                   min_distance=0.01,
                                   search_window=5,
                                   precision_limit=10**(-10),
                                   num_iter_max=100):
        """
        finds image position source position and lense model

        :param sourcePos_x: source position in units of angle
        :param sourcePos_y: source position in units of angle
        :param kwargs_lens: lens model parameters as keyword arguments
        :param min_distance: minimum separation to consider for two images in units of angle
        :param search_window: window size to be considered by the solver. Will not find image position outside this window
        :param precision_limit: required precision in the lens equation solver (in units of angle in the source plane).
        :param num_iter_max: maximum iteration of lens-source mapping conducted by solver to match the required precision
        :returns:  (exact) angular position of (multiple) images ra_pos, dec_pos in units of angle
        :raises: AttributeError, KeyError
        """
        # compute number of pixels to cover the search window with the required min_distance
        numPix = int(round(search_window / min_distance) + 0.5)
        x_grid, y_grid = util.make_grid(numPix, min_distance)
        # ray-shoot to find the relative distance to the required source position for each grid point
        x_mapped, y_mapped = self.lensModel.ray_shooting(
            x_grid, y_grid, kwargs_lens)
        absmapped = util.displaceAbs(x_mapped, y_mapped, sourcePos_x,
                                     sourcePos_y)
        # select minima in the grid points and select grid points that do not deviate more than the
        # width of the grid point to a solution of the lens equation
        x_mins, y_mins, delta_map = util.neighborSelect(
            absmapped, x_grid, y_grid)
        x_mins = x_mins[delta_map <= min_distance]
        y_mins = y_mins[delta_map <= min_distance]
        # iterative solving of the lens equation for the selected grid points
        x_mins, y_mins, solver_precision = self._findIterative(
            x_mins, y_mins, sourcePos_x, sourcePos_y, kwargs_lens,
            precision_limit, num_iter_max)
        # only select iterative results that match the precision limit
        x_mins = x_mins[solver_precision <= precision_limit]
        y_mins = y_mins[solver_precision <= precision_limit]
        # find redundant solutions within the min_distance criterion
        x_mins, y_mins = image_util.findOverlap(x_mins, y_mins, min_distance)
        x_mins, y_mins = self.sort_arrival_times(x_mins, y_mins, kwargs_lens)
        #x_mins, y_mins = lenstronomy_util.coordInImage(x_mins, y_mins, numPix, deltapix)

        return x_mins, y_mins
Exemplo n.º 4
0
def solvelenseq_majoraxis(args, Nmeas=200, Nmeas_extra=50):
    """Solve the lens equation, where the arguments have been properly rotated to the major-axis"""
    b, t, y1, y2, q, gamma1, gamma2 = args
    p1 = np.arctan2(y2 * (1 - gamma1) + gamma2 * y1,
                    y1 * (1 + gamma1) + gamma2 * y2)
    int_points = [p1]
    geom = geomlinspace(1e-4, 0.1, Nmeas_extra)

    thpl = np.sort(
        np.concatenate((
            np.linspace(0., np.pi, Nmeas),
            *[i % np.pi - geom for i in int_points],
            *[i % np.pi + geom for i in int_points],
        )))
    the = _getphi(thpl, (b, t, y1, y2, q, gamma1, gamma2))
    thetas = np.concatenate((the, the + np.pi))
    Rs = np.array(
        [_getr(theta, (b, t, y1, y2, q, gamma1, gamma2)) for theta in thetas])
    stuff = np.array(pol_to_cart(Rs[Rs > 0], thetas[Rs > 0]))
    diff = -y1 - y2 * 1j + stuff[0] + stuff[1] * 1j - _alpha_epl_shear(
        stuff[0], stuff[1], b, q, t, gamma1=gamma1, gamma2=gamma2)
    goodones = np.abs(diff) < 1e-8
    return findOverlap(*stuff[:, goodones], 1e-8)
    def image_position_from_source(self,
                                   sourcePos_x,
                                   sourcePos_y,
                                   kwargs_lens,
                                   min_distance=0.1,
                                   search_window=10,
                                   precision_limit=10**(-10),
                                   num_iter_max=100,
                                   arrival_time_sort=True,
                                   initial_guess_cut=True,
                                   verbose=False,
                                   x_center=0,
                                   y_center=0,
                                   num_random=0,
                                   non_linear=False,
                                   magnification_limit=None):
        """
        finds image position source position and lense model

        :param sourcePos_x: source position in units of angle
        :param sourcePos_y: source position in units of angle
        :param kwargs_lens: lens model parameters as keyword arguments
        :param min_distance: minimum separation to consider for two images in units of angle
        :param search_window: window size to be considered by the solver. Will not find image position outside this window
        :param precision_limit: required precision in the lens equation solver (in units of angle in the source plane).
        :param num_iter_max: maximum iteration of lens-source mapping conducted by solver to match the required precision
        :param arrival_time_sort: bool, if True, sorts image position in arrival time (first arrival photon first listed)
        :param initial_guess_cut: bool, if True, cuts initial local minima selected by the grid search based on distance criteria from the source position
        :param verbose: bool, if True, prints some useful information for the user
        :param x_center: float, center of the window to search for point sources
        :param y_center: float, center of the window to search for point sources
        :param non_linear: bool, if True applies a non-linear solver not dependent on Hessian computation
        :returns: (exact) angular position of (multiple) images ra_pos, dec_pos in units of angle
        :raises: AttributeError, KeyError
        """
        kwargs_lens = self._static_lens_settings(kwargs_lens)

        # compute number of pixels to cover the search window with the required min_distance
        numPix = int(round(search_window / min_distance) + 0.5)
        x_grid, y_grid = util.make_grid(numPix, min_distance)
        x_grid += x_center
        y_grid += y_center
        # ray-shoot to find the relative distance to the required source position for each grid point
        x_mapped, y_mapped = self.lensModel.ray_shooting(
            x_grid, y_grid, kwargs_lens)
        absmapped = util.displaceAbs(x_mapped, y_mapped, sourcePos_x,
                                     sourcePos_y)
        # select minima in the grid points and select grid points that do not deviate more than the
        # width of the grid point to a solution of the lens equation
        x_mins, y_mins, delta_map = util.neighborSelect(
            absmapped, x_grid, y_grid)
        if verbose is True:
            print(
                "There are %s regions identified that could contain a solution of the lens equation"
                % len(x_mins))
        #mag = np.abs(mag)
        #print(x_mins, y_mins, 'before requirement of min_distance')
        if len(x_mins) < 1:
            return x_mins, y_mins
        if initial_guess_cut is True:
            mag = np.abs(
                self.lensModel.magnification(x_mins, y_mins, kwargs_lens))
            mag[mag < 1] = 1
            x_mins = x_mins[delta_map <= min_distance * mag * 5]
            y_mins = y_mins[delta_map <= min_distance * mag * 5]
            if verbose is True:
                print(
                    "The number of regions that meet the plausibility criteria are %s"
                    % len(x_mins))
        x_mins = np.append(
            x_mins,
            np.random.uniform(low=-search_window / 2 + x_center,
                              high=search_window / 2 + x_center,
                              size=num_random))
        y_mins = np.append(
            y_mins,
            np.random.uniform(low=-search_window / 2 + y_center,
                              high=search_window / 2 + y_center,
                              size=num_random))
        # iterative solving of the lens equation for the selected grid points
        x_mins, y_mins, solver_precision = self._findIterative(
            x_mins,
            y_mins,
            sourcePos_x,
            sourcePos_y,
            kwargs_lens,
            precision_limit,
            num_iter_max,
            verbose=verbose,
            min_distance=min_distance,
            non_linear=non_linear)
        # only select iterative results that match the precision limit
        x_mins = x_mins[solver_precision <= precision_limit]
        y_mins = y_mins[solver_precision <= precision_limit]
        # find redundant solutions within the min_distance criterion
        x_mins, y_mins = image_util.findOverlap(x_mins, y_mins, min_distance)
        if arrival_time_sort is True:
            x_mins, y_mins = self.sort_arrival_times(x_mins, y_mins,
                                                     kwargs_lens)
        self._make_dynamic()
        if magnification_limit is not None:
            mag = np.abs(
                self.lensModel.magnification(x_mins, y_mins, kwargs_lens))
            x_mins = x_mins[mag >= magnification_limit]
            y_mins = y_mins[mag >= magnification_limit]
        return x_mins, y_mins
Exemplo n.º 6
0
    def image_position_from_source(self,
                                   sourcePos_x,
                                   sourcePos_y,
                                   kwargs_lens,
                                   min_distance=0.1,
                                   search_window=10,
                                   precision_limit=10**(-10),
                                   num_iter_max=100,
                                   arrival_time_sort=True,
                                   initial_guess_cut=True,
                                   verbose=False,
                                   x_center=0,
                                   y_center=0,
                                   num_random=0,
                                   non_linear=False,
                                   magnification_limit=None):
        """
        finds image position source position and lens model

        :param sourcePos_x: source position in units of angle
        :param sourcePos_y: source position in units of angle
        :param kwargs_lens: lens model parameters as keyword arguments
        :param min_distance: minimum separation to consider for two images in units of angle
        :param search_window: window size to be considered by the solver. Will not find image position outside this window
        :param precision_limit: required precision in the lens equation solver (in units of angle in the source plane).
        :param num_iter_max: maximum iteration of lens-source mapping conducted by solver to match the required precision
        :param arrival_time_sort: bool, if True, sorts image position in arrival time (first arrival photon first listed)
        :param initial_guess_cut: bool, if True, cuts initial local minima selected by the grid search based on distance criteria from the source position
        :param verbose: bool, if True, prints some useful information for the user
        :param x_center: float, center of the window to search for point sources
        :param y_center: float, center of the window to search for point sources
        :param num_random: int, number of random positions within the search window to be added to be starting
         positions for the gradient decent solver
        :param non_linear: bool, if True applies a non-linear solver not dependent on Hessian computation
        :param magnification_limit: None or float, if set will only return image positions that have an
         abs(magnification) larger than this number
        :returns: (exact) angular position of (multiple) images ra_pos, dec_pos in units of angle
        :raises: AttributeError, KeyError
        """
        # find pixels in the image plane possibly hosting a solution of the lens equation, related source distances and pixel width
        x_mins, y_mins, delta_map, pixel_width = self.candidate_solutions(
            sourcePos_x, sourcePos_y, kwargs_lens, min_distance, search_window,
            verbose, x_center, y_center)
        if verbose is True:
            print(
                "There are %s regions identified that could contain a solution of the lens equation"
                % len(x_mins))
        #mag = np.abs(mag)
        #print(x_mins, y_mins, 'before requirement of min_distance')
        if len(x_mins) < 1:
            return x_mins, y_mins
        if initial_guess_cut is True:
            mag = np.abs(
                self.lensModel.magnification(x_mins, y_mins, kwargs_lens))
            mag[mag < 1] = 1
            x_mins = x_mins[delta_map <= min_distance * mag * 5]
            y_mins = y_mins[delta_map <= min_distance * mag * 5]
            if verbose is True:
                print(
                    "The number of regions that meet the plausibility criteria are %s"
                    % len(x_mins))
        x_mins = np.append(
            x_mins,
            np.random.uniform(low=-search_window / 2 + x_center,
                              high=search_window / 2 + x_center,
                              size=num_random))
        y_mins = np.append(
            y_mins,
            np.random.uniform(low=-search_window / 2 + y_center,
                              high=search_window / 2 + y_center,
                              size=num_random))
        # iterative solving of the lens equation for the selected grid points
        x_mins, y_mins, solver_precision = self._find_gradient_decent(
            x_mins,
            y_mins,
            sourcePos_x,
            sourcePos_y,
            kwargs_lens,
            precision_limit,
            num_iter_max,
            verbose=verbose,
            min_distance=min_distance,
            non_linear=non_linear)
        # only select iterative results that match the precision limit
        x_mins = x_mins[solver_precision <= precision_limit]
        y_mins = y_mins[solver_precision <= precision_limit]
        # find redundant solutions within the min_distance criterion
        x_mins, y_mins = image_util.findOverlap(x_mins, y_mins, min_distance)
        if arrival_time_sort is True:
            x_mins, y_mins = self.sort_arrival_times(x_mins, y_mins,
                                                     kwargs_lens)
        if magnification_limit is not None:
            mag = np.abs(
                self.lensModel.magnification(x_mins, y_mins, kwargs_lens))
            x_mins = x_mins[mag >= magnification_limit]
            y_mins = y_mins[mag >= magnification_limit]
        self.lensModel.set_dynamic()
        return x_mins, y_mins
Exemplo n.º 7
0
    def image_position_from_source(self,
                                   sourcePos_x,
                                   sourcePos_y,
                                   kwargs_lens,
                                   min_distance=0.1,
                                   search_window=10,
                                   precision_limit=10**(-10),
                                   num_iter_max=100,
                                   arrival_time_sort=True,
                                   initial_guess_cut=True,
                                   verbose=False):
        """
        finds image position source position and lense model

        :param sourcePos_x: source position in units of angle
        :param sourcePos_y: source position in units of angle
        :param kwargs_lens: lens model parameters as keyword arguments
        :param min_distance: minimum separation to consider for two images in units of angle
        :param search_window: window size to be considered by the solver. Will not find image position outside this window
        :param precision_limit: required precision in the lens equation solver (in units of angle in the source plane).
        :param num_iter_max: maximum iteration of lens-source mapping conducted by solver to match the required precision
        :param arrival_time_sort: bool, if True, sorts image position in arrival time (first arrival photon first listed)
        :param initial_guess_cut: bool, if True, cuts initial local minima selected by the grid search based on
        distance criteria from the source position
        :returns: (exact) angular position of (multiple) images ra_pos, dec_pos in units of angle
        :raises: AttributeError, KeyError
        """

        # compute number of pixels to cover the search window with the required min_distance
        numPix = int(round(search_window / min_distance) + 0.5)
        x_grid, y_grid = util.make_grid(numPix, min_distance)
        # ray-shoot to find the relative distance to the required source position for each grid point
        x_mapped, y_mapped = self.lensModel.ray_shooting(
            x_grid, y_grid, kwargs_lens)
        absmapped = util.displaceAbs(x_mapped, y_mapped, sourcePos_x,
                                     sourcePos_y)
        # select minima in the grid points and select grid points that do not deviate more than the
        # width of the grid point to a solution of the lens equation
        x_mins, y_mins, delta_map = util.neighborSelect(
            absmapped, x_grid, y_grid)
        if verbose is True:
            print(
                "There are %s regions identified that could contain a solution of the lens equation"
                % len(x_mins))
        #mag = np.abs(mag)
        #print(x_mins, y_mins, 'before requirement of min_distance')
        if initial_guess_cut is True:
            mag = np.abs(
                self.lensModel.magnification(x_mins, y_mins, kwargs_lens))
            x_mins = x_mins[delta_map <= min_distance * mag * 5]
            y_mins = y_mins[delta_map <= min_distance * mag * 5]
            if verbose is True:
                print(
                    "The number of regions that meet the plausibility criteria are %s"
                    % len(x_mins))
        #print(x_mins, y_mins, 'after requirement of min_distance')
        # iterative solving of the lens equation for the selected grid points
        x_mins, y_mins, solver_precision = self._findIterative(x_mins,
                                                               y_mins,
                                                               sourcePos_x,
                                                               sourcePos_y,
                                                               kwargs_lens,
                                                               precision_limit,
                                                               num_iter_max,
                                                               verbose=verbose)
        # only select iterative results that match the precision limit
        x_mins = x_mins[solver_precision <= precision_limit]
        y_mins = y_mins[solver_precision <= precision_limit]
        #print(x_mins, y_mins, 'after precision limit requirement')
        # find redundant solutions within the min_distance criterion
        x_mins, y_mins = image_util.findOverlap(x_mins, y_mins, min_distance)
        #print(x_mins, y_mins, 'after overlap removals')
        if arrival_time_sort is True:
            x_mins, y_mins = self.sort_arrival_times(x_mins, y_mins,
                                                     kwargs_lens)
        #x_mins, y_mins = lenstronomy_util.coordInImage(x_mins, y_mins, numPix, deltapix)
        return x_mins, y_mins