Ejemplo n.º 1
0
    def __init__(self, galaxies, cosmology):
        """An abstract plane which represents a set of galaxies at a given redshift.

        From a plane, the surface-density, potential and deflection angles of the galaxies can be computed, as well as \
        cosmological quantities like angular diameter distances..

        Parameters
        -----------
        galaxies : [Galaxy]
            The list of lens galaxies in this plane.
        cosmology : astropy.cosmology
            The cosmology associated with the plane, used to convert arc-second coordinates to physical values.
        """

        self.galaxies = galaxies

        if not galaxies:
            raise exc.RayTracingException('An empty list of galaxies was supplied to Plane')

        if any([redshift is not None for redshift in self.galaxy_redshifts]):
            if not all([galaxies[0].redshift == galaxy.redshift for galaxy in galaxies]):
                raise exc.RayTracingException('The galaxies supplied to A Plane have different redshifts or one galaxy '
                                              'does not have a redshift.')

        self.cosmology = cosmology
Ejemplo n.º 2
0
    def __init__(self, redshift, galaxies, cosmology):
        """A plane of galaxies where all galaxies are at the same redshift.

        Parameters
        -----------
        redshift : float or None
            The redshift of the plane.
        galaxies : [Galaxy]
            The list of galaxies in this plane.
        cosmology : astropy.cosmology
            The cosmology associated with the plane, used to convert arc-second coordinates to physical values.
        """

        if redshift is None:

            if not galaxies:
                raise exc.RayTracingException(
                    "A redshift and no galaxies were input to a Plane. A redshift for the Plane therefore cannot be"
                    "determined")
            elif not all([
                    galaxies[0].redshift == galaxy.redshift
                    for galaxy in galaxies
            ]):
                raise exc.RayTracingException(
                    "A redshift and two or more galaxies with different redshifts were input to a Plane. A unique "
                    "Redshift for the Plane therefore cannot be determined")
            else:
                redshift = galaxies[0].redshift

        self.redshift = redshift
        self.galaxies = galaxies
        self.cosmology = cosmology
Ejemplo n.º 3
0
 def image_plane_images_for_simulation(self):
     if not self.has_padded_grid_stack:
         raise exc.RayTracingException(
             'To retrieve an image plane image for the simulation, the grid_stack in the tracer_normal'
             'must be padded grid_stack')
     return list(map(lambda image_plane_image_1d, grid_stack :
                     grid_stack.regular.map_to_2d_keep_padded(padded_array_1d=image_plane_image_1d),
                     self.image_plane_images_1d, self.grid_stacks))
Ejemplo n.º 4
0
def ordered_plane_redshifts_from_lens_source_plane_redshifts_and_slice_sizes(
        lens_redshifts, planes_between_lenses, source_plane_redshift):
    """Given a set of lens plane redshifts, the source-plane redshift and the number of planes between each, setup the \
    plane redshifts using these values. A lens redshift corresponds to the 'main' lens galaxy(s),
    whereas the slices collect line-of-sight halos over a range of redshifts.

    The source-plane redshift is removed from the ordered plane redshifts that are returned, so that galaxies are not \
    planed at the source-plane redshift.

    For example, if the main plane redshifts are [1.0, 2.0], and the bin sizes are [1,3], the following redshift \
    slices for planes will be used:

    z=0.5
    z=1.0
    z=1.25
    z=1.5
    z=1.75
    z=2.0

    Parameters
    -----------
    lens_redshifts : [float]
        The redshifts of the main-planes (e.g. the lens galaxy), which determine where redshift intervals are placed.
    planes_between_lenses : [int]
        The number of slices between each main plane. The first entry in this list determines the number of slices \
        between Earth (redshift 0.0) and main plane 0, the next between main planes 0 and 1, etc.
    source_plane_redshift : float
        The redshift of the source-plane, which is input explicitly to ensure galaxies are not placed in the \
        source-plane.
    """

    # Check that the number of slices between lens planes is equal to the number of intervals between the lens planes.
    if len(lens_redshifts) != len(planes_between_lenses) - 1:
        raise exc.RayTracingException(
            "The number of lens_plane_redshifts input is not equal to the number of "
            "slices_between_lens_planes+1.")

    plane_redshifts = []

    # Add redshift 0.0 and the source plane redshifit to the lens plane redshifts, so that calculation below can use
    # them when dividing slices. These will be removed by the return function at the end from the plane redshifts.

    lens_redshifts.insert(0, 0.0)
    lens_redshifts.append(source_plane_redshift)

    for lens_plane_index in range(1, len(lens_redshifts)):

        previous_plane_redshift = lens_redshifts[lens_plane_index - 1]
        plane_redshift = lens_redshifts[lens_plane_index]
        slice_total = planes_between_lenses[lens_plane_index - 1]
        plane_redshifts += list(
            np.linspace(previous_plane_redshift, plane_redshift,
                        slice_total + 2))[1:]

    return plane_redshifts[0:-1]
Ejemplo n.º 5
0
def compute_deflections_at_next_plane(plane_index, total_planes):
    """This function determines whether the tracer should compute the deflections at the next plane.

    This is True if there is another plane after this plane, else it is False..

    Parameters
    -----------
    plane_index : int
        The index of the plane we are deciding if we should compute its deflections.
    total_planes : int
        The total number of planes."""

    if plane_index < total_planes - 1:
        return True
    elif plane_index == total_planes - 1:
        return False
    else:
        raise exc.RayTracingException(
            'A galaxy was not correctly allocated its previous / next redshifts'
        )
Ejemplo n.º 6
0
    def __init__(self,
                 lens_galaxies,
                 image_plane_grid_stacks,
                 borders=None,
                 cosmology=cosmo.Planck15):
        """Ray tracer for a lens system with just an image-plane.

        As there is only 1 plane, there are no ray-tracing calculations. This class is therefore only used for fitting \
        image-plane galaxies with light profiles.

        This tracer has a list of grid-stacks (see grid_stack.GridStack) which are all used for ray-tracing.

        Parameters
        ----------
        lens_galaxies : [Galaxy]
            The list of lens galaxies in the image-plane.
        image_plane_grid_stacks : [grid_stacks.GridStack]
            The image-plane grid stacks which are traced. (each stack includes the regular-grid, sub-grid, \
            blurring-grid, etc.).
        borders : [masks.RegularGridBorder]
            The border of each grid-stacks's regular-grid, which is used to relocate demagnified traced pixels to the \
            source-plane border.
        cosmology : astropy.cosmology.Planck15
            The cosmology of the ray-tracing calculation.
        """
        if not lens_galaxies:
            raise exc.RayTracingException(
                'No lens galaxies have been input into the Tracer')

        image_plane = plane_stack.PlaneStack(
            galaxies=lens_galaxies,
            grid_stacks=image_plane_grid_stacks,
            borders=borders,
            compute_deflections=True,
            cosmology=cosmology)

        super(TracerImagePlaneStack, self).__init__(planes=[image_plane],
                                                    cosmology=cosmology)
Ejemplo n.º 7
0
    def __init__(self,
                 galaxies,
                 image_plane_grid_stacks,
                 borders=None,
                 cosmology=cosmo.Planck15):
        """Ray-tracer for a lens system with any number of planes.

        To perform multi-plane ray-tracing, the cosmology that is input is used to rescale deflection-angles \
        according to the lens-geometry of the multi-plane system. All galaxies input to the tracer must therefore \
        have redshifts.

        This tracer has a list of grid-stacks (see grid_stack.GridStack) which are all used for ray-tracing.

        Parameters
        ----------
        galaxies : [Galaxy]
            The list of galaxies in the ray-tracing calculation.
        image_plane_grid_stacks : [grid_stacks.GridStack]
            The image-plane grid stacks which are traced. (each stack includes the regular-grid, sub-grid, \
            blurring-grid, etc.).
        borders : [masks.RegularGridBorder]
            The border of each grid-stacks's regular-grid, which is used to relocate demagnified traced pixels to the \
            source-plane border.
        cosmology : astropy.cosmology
            The cosmology of the ray-tracing calculation.
        """

        ordered_redshifts = lens_util.ordered_plane_redshifts_from_galaxies(
            galaxies=galaxies)

        galaxies_in_redshift_ordered_lists = \
            lens_util.galaxies_in_redshift_ordered_planes_from_galaxies(galaxies=galaxies,
                                                                               plane_redshifts=ordered_redshifts)

        image_plane_grid_stacks = list(
            map(
                lambda grid_stack: pix.
                setup_image_plane_pixelization_grid_from_galaxies_and_grid_stack(
                    galaxies=galaxies, grid_stack=grid_stack),
                image_plane_grid_stacks))

        planes = []

        for plane_index in range(0, len(ordered_redshifts)):

            if plane_index < len(ordered_redshifts) - 1:
                compute_deflections = True
            elif plane_index == len(ordered_redshifts) - 1:
                compute_deflections = False
            else:
                raise exc.RayTracingException(
                    'A galaxy was not correctly allocated its previous / next redshifts'
                )

            new_grid_stacks = image_plane_grid_stacks

            if plane_index > 0:
                for previous_plane_index in range(plane_index):

                    scaling_factor = lens_util.scaling_factor_between_redshifts_for_cosmology(
                        z1=ordered_redshifts[previous_plane_index],
                        z2=ordered_redshifts[plane_index],
                        z_final=ordered_redshifts[-1],
                        cosmology=cosmology)

                    def scale(grid):
                        return np.multiply(scaling_factor, grid)

                    if planes[
                            previous_plane_index].deflection_stacks is not None:
                        scaled_deflections = list(
                            map(
                                lambda deflection_stack: deflection_stack.
                                apply_function(scale),
                                planes[previous_plane_index].deflection_stacks)
                        )
                    else:
                        scaled_deflections = None

                    if scaled_deflections is not None:

                        def minus(grid, deflections):
                            return grid - deflections

                        new_grid_stacks = list(
                            map(
                                lambda grid, deflections: grid.map_function(
                                    minus, deflections), new_grid_stacks,
                                scaled_deflections))

            planes.append(
                plane_stack.PlaneStack(
                    galaxies=galaxies_in_redshift_ordered_lists[plane_index],
                    grid_stacks=new_grid_stacks,
                    borders=borders,
                    compute_deflections=compute_deflections,
                    cosmology=cosmology))

        super(TracerMultiPlanesStack, self).__init__(planes=planes,
                                                     cosmology=cosmology)
Ejemplo n.º 8
0
    def __init__(self,
                 galaxies,
                 image_plane_positions,
                 cosmology=cosmo.Planck15):
        """Positional ray-tracer for a lens system with any number of planes.

        To perform multi-plane ray-tracing, a cosmology must be supplied so that deflection-angles can be rescaled \
        according to the lens-geometry of the multi-plane system.

        Parameters
        ----------
        galaxies : [Galaxy]
            The list of galaxies in the ray-tracing calculation.
        image_plane_positions : [[[]]]
            The (y,x) arc-second coordinates of image-plane pixels which (are expected to) mappers to the same location(s) \
            in the final source-plane.
        cosmology : astropy.cosmology
            The cosmology of the ray-tracing calculation.
        """

        ordered_redshifts = lens_util.ordered_plane_redshifts_from_galaxies(
            galaxies=galaxies)

        galaxies_in_redshift_ordered_lists = \
            lens_util.galaxies_in_redshift_ordered_planes_from_galaxies(galaxies=galaxies,
                                                                               plane_redshifts=ordered_redshifts)

        if not galaxies:
            raise exc.RayTracingException(
                'No galaxies have been input into the Tracer (TracerImageSourcePlanes)'
            )

        planes = []

        for plane_index in range(0, len(ordered_redshifts)):

            if plane_index < len(ordered_redshifts) - 1:
                compute_deflections = True
            elif plane_index == len(ordered_redshifts) - 1:
                compute_deflections = False
            else:
                raise exc.RayTracingException(
                    'A galaxy was not correctly allocated its previous / next redshifts'
                )

            new_positions = image_plane_positions

            if plane_index > 0:
                for previous_plane_index in range(plane_index):

                    scaling_factor = lens_util.scaling_factor_between_redshifts_for_cosmology(
                        z1=ordered_redshifts[previous_plane_index],
                        z2=ordered_redshifts[plane_index],
                        z_final=ordered_redshifts[-1],
                        cosmology=cosmology)

                    scaled_deflections = list(
                        map(
                            lambda deflections: np.multiply(
                                scaling_factor, deflections),
                            planes[previous_plane_index].deflections))

                    new_positions = list(
                        map(
                            lambda positions, deflections: np.subtract(
                                positions, deflections), new_positions,
                            scaled_deflections))

            planes.append(
                pl.PlanePositions(
                    galaxies=galaxies_in_redshift_ordered_lists[plane_index],
                    positions=new_positions,
                    compute_deflections=compute_deflections))

        super(TracerMultiPlanesPositions, self).__init__(planes=planes,
                                                         cosmology=cosmology)