def test__positions_found_for_simple_mass_profile_list(self): grid = al.Grid2D.uniform(shape_native=(100, 100), pixel_scales=0.05) sis = al.mp.SphIsothermal(centre=(0.0, 0.0), einstein_radius=1.0) solver = al.PointSolver(grid=grid, pixel_scale_precision=0.01) positions = solver.solve(lensing_obj=sis, source_plane_coordinate=(0.0, 0.11)) assert positions[0] == pytest.approx(np.array([0.003125, -0.890625]), 1.0e-4) assert positions[3] == pytest.approx(np.array([-0.003125, 1.109375]), 1.0e-4) grid = al.Grid2D.uniform(shape_native=(100, 100), pixel_scales=0.05, sub_size=1) g0 = al.Galaxy( redshift=0.5, mass=al.mp.EllIsothermal( centre=(0.001, 0.001), einstein_radius=1.0, elliptical_comps=(0.0, 0.111111), ), ) g1 = al.Galaxy(redshift=1.0) tracer = al.Tracer.from_galaxies(galaxies=[g0, g1]) solver = PointSolver(grid=grid, pixel_scale_precision=0.01) coordinates = solver.solve(lensing_obj=tracer, source_plane_coordinate=(0.0, 0.0)) assert coordinates.in_list[0] == pytest.approx((1.028125, -0.003125), 1.0e-4) assert coordinates.in_list[1] == pytest.approx((0.009375, -0.95312), 1.0e-4) assert coordinates.in_list[2] == pytest.approx((0.009375, 0.95312), 1.0e-4) assert coordinates.in_list[3] == pytest.approx((-1.028125, -0.003125), 1.0e-4)
def test__multi_plane_position_solving(self): grid = al.Grid2D.uniform(shape_native=(100, 100), pixel_scales=0.05, sub_size=1) g0 = al.Galaxy(redshift=0.5, mass=al.mp.SphIsothermal(einstein_radius=1.0)) g1 = al.Galaxy(redshift=1.0, point_0=al.ps.Point(centre=(0.1, 0.1))) g2 = al.Galaxy(redshift=2.0, point_1=al.ps.Point(centre=(0.1, 0.1))) tracer = al.Tracer.from_galaxies(galaxies=[g0, g1, g2]) positions = al.Grid2DIrregular([(0.0, 0.0), (3.0, 4.0)]) noise_map = al.ValuesIrregular([0.5, 1.0]) point_solver = al.PointSolver(grid=grid, pixel_scale_precision=0.01) fit_0 = al.FitPositionsImage( name="point_0", positions=positions, noise_map=noise_map, tracer=tracer, point_solver=point_solver, ) fit_1 = al.FitPositionsImage( name="point_1", positions=positions, noise_map=noise_map, tracer=tracer, point_solver=point_solver, ) scaling_factor = al.util.cosmology.scaling_factor_between_redshifts_from( redshift_0=0.5, redshift_1=1.0, redshift_final=2.0, cosmology=tracer.cosmology, ) assert fit_0.model_positions[0, 0] == pytest.approx( scaling_factor * fit_1.model_positions[0, 0], 1.0e-1) assert fit_0.model_positions[0, 1] == pytest.approx( scaling_factor * fit_1.model_positions[0, 1], 1.0e-1)
""" tracer_plotter = aplt.TracerPlotter(tracer=tracer, grid=grid) tracer_plotter.figures_2d(image=True) """ __Point Source__ It is common for group-scale strong lens datasets to be modeled assuming that the source is a point-source. Even if it isn't, this can be necessary due to computational run-time making it unfeasible to fit the imaging dataset outright. We will use a `PositionSolver` to locate the multiple images, using computationally slow but robust settings to ensure w e accurately locate the image-plane positions. """ solver = al.PointSolver( grid=grid, use_upscaling=True, pixel_scale_precision=0.001, upscale_factor=2, magnification_threshold=1.0, ) """ We now pass the `Tracer` to the solver. This will then find the image-plane coordinates that map directly to the source-plane coordinate (0.0", 0.0"). """ positions = solver.solve(lensing_obj=tracer, source_plane_coordinate=source_galaxy.point_0.centre) positions = al.Grid2DIrregular(grid=[ positions.in_list[0], positions.in_list[2], positions.in_list[3], positions.in_list[-1],
galaxies=[lens_galaxy, source_galaxy_0, source_galaxy_1]) """ We will use a `PositionSolver` to locate the multiple images. We will use computationally slow but robust settings to ensure we accurately locate the image-plane positions. """ grid = al.Grid2D.uniform( shape_native=(100, 100), pixel_scales= 0.05, # <- The pixel-scale describes the conversion from pixel units to arc-seconds. ) solver = al.PointSolver( grid=grid, use_upscaling=True, upscale_factor=2, pixel_scale_precision=0.001, distance_to_source_centre=0.001, ) """ We now pass the `Tracer` to the solver. This will then find the image-plane coordinates that map directly to the source-plane coordinate (0.0", 0.0"). """ positions_0 = solver.solve( lensing_obj=tracer, source_plane_coordinate=source_galaxy_0.point_0.centre, upper_plane_index=1, ) # We are still improving the PositionSolver, this is a hack to get it to give sensible positions for now.
Use these galaxies to setup a tracer, which will compute the multiple image positions of the simulated dataset. """ tracer = al.Tracer.from_galaxies(galaxies=[lens_galaxy, source_galaxy]) """ We will use a `PositionSolver` to locate the multiple images. We will use computationally slow but robust settings to ensure we accurately locate the image-plane positions. """ grid = al.Grid2D.uniform( shape_native=(100, 100), pixel_scales=0.05, # <- The pixel-scale describes the conversion from pixel units to arc-seconds. ) solver = al.PointSolver( grid=grid, use_upscaling=True, pixel_scale_precision=0.001, upscale_factor=2 ) """ We now pass the `Tracer` to the solver. This will then find the image-plane coordinates that map directly to the source-plane coordinate (0.0", 0.0"). """ positions = solver.solve( lensing_obj=tracer, source_plane_coordinate=source_galaxy.point_0.centre ) """ Use the positions to compute the magnification of the `Tracer` at every position. """ magnifications = tracer.magnification_2d_via_hessian_from(grid=positions)
grid_plotter.figure_2d() """ __PositionsSolver__ For point-source modeling we also need to define our `PointSolver`. This object determines the multiple-images of a mass model for a point source at location (y,x) in the source plane, by iteratively ray-tracing light rays to the source-plane. Checkout the script ? for a complete description of this object, we will use the default `PositionSolver` in this example with a `point_scale_precision` half the value of the position noise-map, which should be sufficiently good enough precision to fit the lens model accurately. """ grid = al.Grid2D.uniform(shape_native=image.shape_native, pixel_scales=image.pixel_scales) point_solver = al.PointSolver(grid=grid, pixel_scale_precision=0.025) """ __Model__ We compose our lens model using `Model` objects, which represent the galaxies we fit to our data. In this example we fit a lens model where: - There are three lens galaxy's with `SphIsothermal` total mass distributions, with the prior on the centre of each profile informed by its observed centre of light [9 parameters]. - The source galaxy's light is a point `PointFlux` [3 parameters]. The number of free parameters and therefore the dimensionality of non-linear parameter space is N=12. __Model JSON File_ For group modeling, there can be many lens and source galaxies. Manually writing the model in a Python script, in the
def make_point_solver(): grid = al.Grid2D.uniform(shape_native=(10, 10), pixel_scales=0.5) return al.PointSolver(grid=grid, pixel_scale_precision=0.25)