def __init__(self, lens_galaxies, source_galaxies, image_plane_grid_stack, border=None, cosmology=cosmo.Planck15): """Ray-tracer for a lens system with two planes, an image-plane and source-plane. This tracer has only one grid-stack (see grid_stack.GridStack) which is used for ray-tracing. Parameters ---------- lens_galaxies : [Galaxy] The list of galaxies in the image-plane. source_galaxies : [Galaxy] The list of galaxies in the source-plane. image_plane_grid_stack : grid_stacks.GridStack The image-plane grid stack which is traced. (includes the regular-grid, sub-grid, blurring-grid, etc.). border : masks.RegularGridBorder The border of the regular-grid, which is used to relocate demagnified traced pixels to the \ source-plane borders. cosmology : astropy.cosmology.Planck15 The cosmology of the ray-tracing calculation. """ image_plane_grid_stack = pix.setup_image_plane_pixelization_grid_from_galaxies_and_grid_stack( galaxies=source_galaxies, grid_stack=image_plane_grid_stack) image_plane = pl.Plane(galaxies=lens_galaxies, grid_stack=image_plane_grid_stack, border=border, compute_deflections=True, cosmology=cosmology) source_plane_grid_stack = image_plane.trace_grid_stack_to_next_plane() source_plane = pl.Plane(galaxies=source_galaxies, grid_stack=source_plane_grid_stack, border=border, compute_deflections=False, cosmology=cosmology) super(TracerImageSourcePlanes, self).__init__(planes=[image_plane, source_plane], cosmology=cosmology)
def from_galaxies(cls, galaxies, cosmology=cosmo.Planck15): plane_redshifts = lens_util.ordered_plane_redshifts_from_galaxies( galaxies=galaxies) galaxies_in_planes = lens_util.galaxies_in_redshift_ordered_planes_from_galaxies( galaxies=galaxies, plane_redshifts=plane_redshifts) planes = [] for plane_index in range(0, len(plane_redshifts)): planes.append( pl.Plane(galaxies=galaxies_in_planes[plane_index], cosmology=cosmology)) return Tracer(planes=planes, cosmology=cosmology)
def test__grid_stack_has_deflections_subtracted_from_it( self, grid_stack, galaxy_mass): plane = pl.Plane(galaxies=[galaxy_mass], grid_stack=grid_stack) deflection_stack = lens_util.scaled_deflection_stack_from_plane_and_scaling_factor( plane=plane, scaling_factor=3.0) traced_grid_stack = lens_util.grid_stack_from_deflection_stack( grid_stack=grid_stack, deflection_stack=deflection_stack) assert (traced_grid_stack.regular == grid_stack.regular - deflection_stack.regular).all() assert (traced_grid_stack.sub == grid_stack.sub - deflection_stack.sub).all() assert (traced_grid_stack.blurring == grid_stack.blurring - deflection_stack.blurring).all()
def grid_at_redshift_from_grid_and_redshift(self, grid, redshift): """For an input grid of (y,x) arc-second image-plane coordinates, ray-trace the coordinates to any redshift in \ the strong lens configuration. This is performed using multi-plane ray-tracing and the existing redshifts and planes of the tracer. However, \ any redshift can be input even if a plane does not exist there, including redshifts before the first plane \ of the lens system. Parameters ---------- grid : ndsrray or aa.Grid The image-plane grid which is traced to the redshift. redshift : float The redshift the image-plane grid is traced to. """ if redshift <= self.plane_redshifts[0]: return grid.copy() plane_index_with_redshift = [ plane_index for plane_index, plane in enumerate(self.planes) if plane.redshift == redshift ] if plane_index_with_redshift: return self.traced_grids_of_planes_from_grid(grid=grid)[ plane_index_with_redshift[0] ] for plane_index, plane_redshift in enumerate(self.plane_redshifts): if redshift < plane_redshift: plane_index_insert = plane_index planes = self.planes planes.insert( plane_index_insert, pl.Plane(redshift=redshift, galaxies=[], cosmology=self.cosmology), ) tracer = Tracer(planes=planes, cosmology=self.cosmology) return tracer.traced_grids_of_planes_from_grid(grid=grid)[plane_index_insert]
def __init__(self, lens_galaxies, image_plane_grid_stack, border=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 only one grid-stack (see grid_stack.GridStack) which is used for ray-tracing. Parameters ---------- lens_galaxies : [Galaxy] The list of lens galaxies in the image-plane. image_plane_grid_stack : grid_stacks.GridStack The image-plane grid stack which is traced. (includes the regular-grid, sub-grid, blurring-grid, etc.). border : masks.RegularGridBorder The border of the regular-grid, which is used to relocate demagnified traced pixels to the \ source-plane borders. cosmology : astropy.cosmology 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 = pl.Plane(galaxies=lens_galaxies, grid_stack=image_plane_grid_stack, border=border, compute_deflections=True, cosmology=cosmology) super(TracerImagePlane, self).__init__(planes=[image_plane], cosmology=cosmology)
def test__deflection_stack_is_scaled_by_scaling_factor( self, grid_stack, galaxy_mass): plane = pl.Plane(galaxies=[galaxy_mass], grid_stack=grid_stack) scaled_deflection_stack = lens_util.scaled_deflection_stack_from_plane_and_scaling_factor( plane=plane, scaling_factor=1.0) assert (scaled_deflection_stack.regular == plane.deflection_stack.regular).all() assert ( scaled_deflection_stack.sub == plane.deflection_stack.sub).all() assert (scaled_deflection_stack.blurring == plane.deflection_stack.blurring).all() scaled_deflection_stack = lens_util.scaled_deflection_stack_from_plane_and_scaling_factor( plane=plane, scaling_factor=2.0) assert (scaled_deflection_stack.regular == 2.0 * plane.deflection_stack.regular).all() assert (scaled_deflection_stack.sub == 2.0 * plane.deflection_stack.sub).all() assert (scaled_deflection_stack.blurring == 2.0 * plane.deflection_stack.blurring).all()
def sliced_tracer_from_lens_line_of_sight_and_source_galaxies( cls, lens_galaxies, line_of_sight_galaxies, source_galaxies, planes_between_lenses, cosmology=cosmo.Planck15, ): """Ray-tracer for a lens system with any number of planes. The redshift of these planes are specified by the input parameters *lens_redshifts* and \ *slices_between_main_planes*. Every galaxy is placed in its closest plane in redshift-space. 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. All galaxies input to the tracer must therefore \ have redshifts. This tracer has only one grid (see gridStack) which is used for ray-tracing. Parameters ---------- lens_galaxies : [Galaxy] The list of galaxies in the ray-tracing calculation. image_plane_grid : grid_stacks.GridStack The image-plane grid which is traced. (includes the grid, sub-grid, blurring-grid, etc.). 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. border : masks.GridBorder The border of the grid, which is used to relocate demagnified traced pixels to the \ source-plane borders. cosmology : astropy.cosmology The cosmology of the ray-tracing calculation. """ lens_redshifts = lens_util.ordered_plane_redshifts_from_galaxies( galaxies=lens_galaxies ) plane_redshifts = lens_util.ordered_plane_redshifts_from_lens_source_plane_redshifts_and_slice_sizes( lens_redshifts=lens_redshifts, planes_between_lenses=planes_between_lenses, source_plane_redshift=source_galaxies[0].redshift, ) galaxies_in_planes = lens_util.galaxies_in_redshift_ordered_planes_from_galaxies( galaxies=lens_galaxies + line_of_sight_galaxies, plane_redshifts=plane_redshifts, ) plane_redshifts.append(source_galaxies[0].redshift) galaxies_in_planes.append(source_galaxies) planes = [] for plane_index in range(0, len(plane_redshifts)): planes.append( pl.Plane( redshift=plane_redshifts[plane_index], galaxies=galaxies_in_planes[plane_index], cosmology=cosmology, ) ) return Tracer(planes=planes, cosmology=cosmology)
def make_plane(galaxy_light, grid_stack): return pl.Plane(galaxies=[galaxy_light], grid_stack=grid_stack)
# As always, we need grids, where our grids are the coordinates we'll 'trace' from the image-plane to the source-plane # in the lensing configuration above. Our grid-stack is therefore no longer just a 'grid-stack', but the grid-stack # representing our image-plane coordinates. Thus, lets name as such. image_plane_grid_stack = grids.GridStack.from_shape_pixel_scale_and_sub_grid_size(shape=(100, 100), pixel_scale=0.05, sub_grid_size=2) # Whereas before we called our galaxy's things like 'galaxy_with_light_profile', lets now refer to them by their role # in lensing, e.g. 'lens_galaxy' and 'source_galaxy'. mass_profile = mass_profiles.SphericalIsothermal(centre=(0.0, 0.0), einstein_radius=1.6) lens_galaxy = galaxy.Galaxy(mass=mass_profile) light_profile = light_profiles.SphericalSersic(centre=(0.0, 0.0), intensity=1.0, effective_radius=1.0, sersic_index=1.0) source_galaxy = galaxy.Galaxy(light=light_profile) # Lets setup our image-plane. This plane takes the lens galaxy we made above and the grid-stack of # image-plane coordinates. image_plane = plane.Plane(galaxies=[lens_galaxy], grid_stack=image_plane_grid_stack) # Up to now, we've kept our galaxies and grids separate, and passed the grid to a galaxy object to compute # its quantities (e.g. to compute light-profile intensities, we'd write galaxy.intensities_from_grid(grid=grid)). # # Plane's combine the galaxies and grids into one object, thus once we've setup a plane there is no longer any need # have to pass it a grid to compute its quantities. Furthermore, once these quantities are in a plane, they are # automatically mapped back to their original 2D grid-arrays. print('deflection-angles of planes regular-grid pixel 1:') print(image_plane.deflections_y[0,0]) print(image_plane.deflections_x[0,0]) print('deflection-angles of planes regular-grid pixel 2:') print(image_plane.deflections_y[0,1]) print(image_plane.deflections_x[0,1]) # Plane plotters also don't need grids passed to them anymore - just the plane itself.
def __init__(self, galaxies, image_plane_grid_stack, border=None, cosmology=cosmo.Planck15): """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. All galaxies input to the tracer must therefore \ have redshifts. This tracer has only one grid-stack (see grid_stack.GridStack) which is used for ray-tracing. Parameters ---------- galaxies : [Galaxy] The list of galaxies in the ray-tracing calculation. image_plane_grid_stack : grid_stacks.GridStack The image-plane grid stack which is traced. (includes the regular-grid, sub-grid, blurring-grid, etc.). border : masks.RegularGridBorder The border of the regular-grid, which is used to relocate demagnified traced pixels to the \ source-plane borders. cosmology : astropy.cosmology The cosmology of the ray-tracing calculation. """ plane_redshifts = lens_util.ordered_plane_redshifts_from_galaxies( galaxies=galaxies) galaxies_in_planes = \ lens_util.galaxies_in_redshift_ordered_planes_from_galaxies(galaxies=galaxies, plane_redshifts=plane_redshifts) image_plane_grid_stack = pix.setup_image_plane_pixelization_grid_from_galaxies_and_grid_stack( galaxies=galaxies, grid_stack=image_plane_grid_stack) planes = [] for plane_index in range(0, len(plane_redshifts)): compute_deflections = lens_util.compute_deflections_at_next_plane( plane_index=plane_index, total_planes=len(plane_redshifts)) new_grid_stack = image_plane_grid_stack if plane_index > 0: for previous_plane_index in range(plane_index): scaling_factor = lens_util.scaling_factor_between_redshifts_for_cosmology( z1=plane_redshifts[previous_plane_index], z2=plane_redshifts[plane_index], z_final=plane_redshifts[-1], cosmology=cosmology) scaled_deflection_stack = lens_util.scaled_deflection_stack_from_plane_and_scaling_factor( plane=planes[previous_plane_index], scaling_factor=scaling_factor) new_grid_stack = \ lens_util.grid_stack_from_deflection_stack(grid_stack=new_grid_stack, deflection_stack=scaled_deflection_stack) planes.append( pl.Plane(galaxies=galaxies_in_planes[plane_index], grid_stack=new_grid_stack, border=border, compute_deflections=compute_deflections, cosmology=cosmology)) super(TracerMultiPlanes, self).__init__(planes=planes, cosmology=cosmology)