def test__via_fit_imaging_from(fit_imaging_x2_plane_7x7, grid_2d_7x7): visuals_2d = aplt.Visuals2D(origin=(1.0, 1.0), vectors=2) include_2d = aplt.Include2D( origin=True, mask=True, border=True, light_profile_centres=True, mass_profile_centres=True, critical_curves=True, ) get_visuals = GetVisuals2D(include=include_2d, visuals=visuals_2d) visuals_2d_via = get_visuals.via_fit_imaging_from( fit=fit_imaging_x2_plane_7x7) assert visuals_2d_via.origin == (1.0, 1.0) assert (visuals_2d_via.mask == fit_imaging_x2_plane_7x7.mask).all() assert (visuals_2d_via.border == fit_imaging_x2_plane_7x7.mask.border_grid_sub_1.binned).all() assert visuals_2d_via.light_profile_centres.in_list == [(0.0, 0.0)] assert visuals_2d_via.mass_profile_centres.in_list == [(0.0, 0.0)] assert (visuals_2d_via.critical_curves[0] == fit_imaging_x2_plane_7x7. tracer.critical_curves_from(grid=grid_2d_7x7)[0]).all() assert visuals_2d_via.vectors == 2 include_2d = aplt.Include2D( origin=False, mask=False, border=False, light_profile_centres=False, mass_profile_centres=False, critical_curves=False, ) get_visuals = GetVisuals2D(include=include_2d, visuals=visuals_2d) visuals_2d_via = get_visuals.via_fit_imaging_from( fit=fit_imaging_x2_plane_7x7) assert visuals_2d_via.origin == (1.0, 1.0) assert visuals_2d_via.mask is None assert visuals_2d_via.border is None assert visuals_2d_via.light_profile_centres is None assert visuals_2d_via.mass_profile_centres is None assert visuals_2d_via.critical_curves is None assert visuals_2d_via.vectors == 2
In this case, our `source_galaxy` only had a ` LightProfile` so only a plot of its image is available. """ plane_plotter = aplt.PlanePlotter(plane=source_plane, grid=lensed_grid) plane_plotter.figures_2d(image=True) """ In addition to the lensed image of the source-plane, we can plot its unlensed image (e.g. how the source-galaxy appears in the source-plane before lensing) using the `figure_plane_image` method. """ plane_plotter.figures_2d(plane_image=True) """ __Visuals__ It is feasible for us to plot the caustics in the source-plane. However, to calculate the `Caustics` we must manually compute them from the image-plane `MassProfile` and pass them to the source-plane mat_plot_2d. """ visuals_2d = aplt.Visuals2D(caustics=image_plane.caustics_from(grid=grid)) plane_plotter = aplt.PlanePlotter(plane=source_plane, grid=lensed_grid, visuals_2d=visuals_2d) plane_plotter.figures_2d(plane_image=True) """ __Include__ For `PlanePlotter`'s, `GalaxyPlotter`'s and `LightProfilePlotter's that are plotting source-plane images, the only way to plot the caustics is to manually extract them from the foreground `MassProfile`'s, as shown above. This is because these source-plane objects have no knowledge of what objects are in the image-plane. `TracerPlotter`'s automatically extract and plot caustics on source-plane figures, given they have available the necessary information on the image-plane mass. This is shown in `autolens_workspace/plot/plotters/TracerPlotter.py`. A `Plane` and its `Grid2D` contains the following attributes which can be plotted automatically via
point_dict = al.PointDict(point_dataset_list=[point_dataset]) point_dict.output_to_json(file_path=path.join(dataset_path, "point_dict.json"), overwrite=True) """ __Imaging__ We can now pass this simulator a tracer, which creates the ray-traced image plotted above and simulates it as an imaging dataset. """ imaging = simulator.via_tracer_from(tracer=tracer, grid=grid) """ Lets plot the simulated `Imaging` dataset before we output it to fits, including the (y,x) coordinates of the multiple images in the image-plane. """ visuals_2d = aplt.Visuals2D(multiple_images=positions) imaging_plotter = aplt.ImagingPlotter(imaging=imaging, visuals_2d=visuals_2d, mat_plot_2d=aplt.MatPlot2D()) imaging_plotter.subplot_imaging() """ Output the simulated dataset to the dataset path as .fits files. """ imaging.output_to_fits( image_path=path.join(dataset_path, "image.fits"), psf_path=path.join(dataset_path, "psf.fits"), noise_map_path=path.join(dataset_path, "noise_map.fits"), overwrite=True, ) """
""" magnifications_0 = tracer.magnification_2d_via_hessian_from(grid=positions_0) magnifications_1 = tracer.magnification_2d_via_hessian_from(grid=positions_1) """ We can now compute the observed fluxes of the `Point`, give we know how much each is magnified. """ flux = 1.0 fluxes_0 = [flux * np.abs(magnification) for magnification in magnifications_0] fluxes_0 = al.ValuesIrregular(values=fluxes_0) fluxes_1 = [flux * np.abs(magnification) for magnification in magnifications_1] fluxes_1 = al.ValuesIrregular(values=fluxes_1) """ We now output the image of this strong lens to `.fits` which can be used for visualize when performing point-source modeling and to `.png` for general inspection. """ visuals_2d = aplt.Visuals2D(multiple_images=[positions_0, positions_1]) tracer_plotter = aplt.TracerPlotter(tracer=tracer, grid=grid, visuals_2d=visuals_2d) tracer_plotter.figures_2d(image=True) mat_plot_2d = aplt.MatPlot2D( output=aplt.Output(path=dataset_path, filename="image_2d", format="fits")) tracer_plotter = aplt.TracerPlotter(tracer=tracer, grid=grid, mat_plot_2d=mat_plot_2d) tracer_plotter.figures_2d(image=True) mat_plot_2d = aplt.MatPlot2D(
__Point Source__ The Source's ring is much larger than other examples (> 5.0") and there are clearly additional galaxies in and around the main lens galaxy. Modeling group scale lenses is challenging, because each individual galaxy must be included in the overall lens model. For this simple overview, we will therefore model the system as a point source, which reduces the complexity of the model and reduces the computational run-time of the model-fit. Lets load the lens's point-source data, where the brightest pixels of the source are used as the locations of its centre: """ point_dict = al.PointDict.from_json( file_path=path.join(dataset_path, "point_dict.json")) visuals_2d = aplt.Visuals2D(positions=point_dict.positions_list) array_plotter = aplt.Array2DPlotter(array=imaging.image, visuals_2d=visuals_2d) array_plotter.figure_2d() """ __PositionsSolver__ Define the position solver used for the point source fitting. """ grid = al.Grid2D.uniform(shape_native=imaging.shape_native, pixel_scales=imaging.pixel_scales) positions_solver = al.PositionsSolver(grid=grid, pixel_scale_precision=0.025) """ __Model__
mask=mask_circular, settings_pixelization=al.SettingsPixelization(use_border=False), ) inversion_plotter = aplt.InversionPlotter(inversion=fit.inversion, include_2d=include_2d) inversion_plotter.figures_2d_of_mapper(mapper_index=0, reconstruction=True) """ Woah, whats happened? There are lots of additional $(y,x)$ coordinates in the source-plane grid, some of which trace to extremely large radii far away from the central regions of the source-plane! These points are the traced image-pixels that correspond to the central image-pixels that the annular mask removed (e.g. they were at radii with 0.8" of the centre). Lets quickly check this by plotting the indexes of these image-pixels. """ visuals_2d = aplt.Visuals2D(indexes=[986, 987, 988, 989, 990, 991]) include_2d = aplt.Include2D(mapper_source_grid_slim=True) mapper_plotter = aplt.MapperPlotter( mapper=fit.inversion.linear_obj_list[0], visuals_2d=visuals_2d, include_2d=include_2d, ) mapper_plotter.subplot_image_and_mapper(image=fit.imaging.image) """ So, why is this happening? What is the mass profile physically doing to create these source plane coordinates at extremely large radial values? Towards the centre of th elliptical isothermal mass profile, the density begins to rise very sharply, it becomes extremely steep or 'cuspy'. This cuspy behaviour towards its centre can cause extremely large deflection angles to be
Only the `LightProfile` centre is used by the position solver, but a light profile is used to visalize the lensed source. """ light_profile = light_profile_model.random_instance() """Setup the lens, source and _Tracer_.""" lens_galaxy = al.Galaxy(redshift=0.5, mass=mass_profile) source_galaxy = al.Galaxy(redshift=1.0, light=light_profile) tracer = al.Tracer.from_galaxies(galaxies=[lens_galaxy, source_galaxy]) """Solve for the positions via the _Tracer_.""" positions = solver.solve( lensing_obj=tracer, source_plane_coordinate=tracer.source_plane.galaxies[0].light.centre, ) """Visually inspect the positions (comment this out if you are confident the code is behaving as expected).""" visuals_2d = aplt.Visuals2D(positions=positions) tracer_plotter = aplt.TracerPlotter(tracer=tracer, grid=grid, visuals_2d=visuals_2d) tracer_plotter.figures(image=True) """Save the `Tracer` and `Positions` so they can be used for testing other `PositionsSolver` settings.""" tracer.save(file_path=pickle_path, filename=f"tracer_{str(i)}") positions.save(file_path=pickle_path, filename=f"positions_{str(i)}")
""" dataset_path = path.join("dataset", "slacs", "slacs1430+4105") image_path = path.join(dataset_path, "image.fits") image = al.Array2D.from_fits(file_path=image_path, hdu=0, pixel_scales=0.03) """ To plot a patch on an image, we use the `matplotlib.patches` module. In this example, we will use the `Ellipse` patch. """ from matplotlib.patches import Ellipse patch_0 = Ellipse(xy=(1.0, 2.0), height=1.0, width=2.0, angle=1.0) patch_1 = Ellipse(xy=(-2.0, -3.0), height=1.0, width=2.0, angle=1.0) """ We input these patches into the `Visuals2D` object, which plots it over the figure. """ visuals_2d = aplt.Visuals2D(patches=[patch_0, patch_1]) """ We now plot the image with the array overlaid. """ array_plotter = aplt.Array2DPlotter(array=image) # , visuals_2d=visuals_2d) array_plotter.figure_2d() """ We can customize the patches using the `Patcher` matplotlib wrapper object which wraps the following method(s): https://matplotlib.org/3.3.2/api/collections_api.html """ patch_overlay = aplt.PatchOverlay(facecolor=["r", "g"], edgecolor="none", linewidth=10, offsets=3.0)
""" First, lets load an example Hubble Space Telescope image of a real strong lens as an `Array2D`. """ dataset_path = path.join("dataset", "slacs", "slacs1430+4105") image_path = path.join(dataset_path, "image.fits") image = al.Array2D.from_fits(file_path=image_path, hdu=0, pixel_scales=0.03) """ We next need the 2D `Array2D` we overlay. We'll create a simple 3x3 array. """ arr = al.Array2D.manual_native(array=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]], pixel_scales=0.5) """ We input this `Array2D` into the `Visuals2D` object, which plots it over the figure. """ visuals_2d = aplt.Visuals2D(array_overlay=arr) """ We now plot the image with the array overlaid. """ array_plotter = aplt.Array2DPlotter(array=image, visuals_2d=visuals_2d) array_plotter.figure_2d() """ We customize the overlaid array using the `ArrayOverlay` matplotlib wrapper object which wraps the following method(s): To overlay the array this objects wrap the following matplotlib method: https://matplotlib.org/3.3.2/api/_as_gen/matplotlib.pyplot.imshow.html """ array_overlay = aplt.ArrayOverlay(alpha=0.5) mat_plot_2d = aplt.MatPlot2D(array_overlay=array_overlay)
""" # %% rectangular = al.pix.Rectangular(shape=(25, 25)) mapper = rectangular.mapper_from_grid_and_sparse_grid(grid=source_plane_grid) # %% """ we're going to plot our `Mapper` alongside the image we used to generate the source-plane grid. """ # %% visuals_2d = aplt.Visuals2D( indexes=[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000], ] ) include_2d = aplt.Include2D(mapper_source_full_grid=True) mapper_plotter = aplt.MapperPlotter( mapper=mapper, visuals_2d=visuals_2d, include_2d=include_2d ) mapper_plotter.subplot_image_and_mapper(image=imaging.image) # %% """ The pixels in the image map to the pixels in the source-plane, and visa-versa. Lets highlight a set of image-pixels in both the image and source-plane. """
include_2d = aplt.Include2D(border=True) array_plotter = aplt.Array2DPlotter(array=masked_image, include_2d=include_2d) array_plotter.figure_2d() """ The appearance of the border is customized using a `BorderScatter` object. To plot the border this object wraps the following matplotlib method: https://matplotlib.org/3.2.2/api/_as_gen/matplotlib.pyplot.scatter.html """ border_scatter = aplt.BorderScatter(marker="o", c="r", s=50) mat_plot_2d = aplt.MatPlot2D(border_scatter=border_scatter) array_plotter = aplt.Array2DPlotter(array=masked_image, mat_plot_2d=mat_plot_2d, include_2d=include_2d) array_plotter.figure_2d() """ To plot the border manually, we can pass it into a` Visuals2D` object. This means we don't need to create the `masked_image` array we used above. """ visuals_2d = aplt.Visuals2D(border=mask.border_grid_1d) array_plotter = aplt.Array2DPlotter(array=image, visuals_2d=visuals_2d) array_plotter.figure_2d() """ Finish. """
# %% """ Woah - whats happened? There are lots of extra points on our source-plane `Grid` which trace to extremely large radii away from the central regions of the source-plane! These points are traced image-pixels (just like all the other points) which correspond to the central image-pixels that our annular `Mask2D` masked but that our circular `Mask2D` didn`t! Lets quickly check this using a `Mapper` `Plotter`. """ # %% visuals_2d = aplt.Visuals2D(indexes=[ [3578, 3579, 3580, 3581, 3582], [3678, 3679, 3680, 3681, 3682], [3778, 3779, 3780, 3781, 3782], [3878, 3879, 3880, 3881, 3882], [3978, 3979, 3980, 3981, 3982], [4078, 4079, 4080, 4081, 4082], [4178, 4179, 4180, 4181, 4182], ]) include_2d = aplt.Include2D(mapper_source_full_grid=True) mapper_plotter = aplt.MapperPlotter(mapper=fit.inversion.mapper, visuals_2d=visuals_2d, include_2d=include_2d) mapper_plotter.subplot_image_and_mapper(image=fit.masked_imaging.image) # %% """ So, whats happening physically? Towards the centre of our `EllipticalIsothermal` `MassProfile`.the density profile
import autolens.plot as aplt """ First, lets load an example Hubble Space Telescope image of a real strong lens as an `Array2D`. """ dataset_path = path.join("dataset", "slacs", "slacs1430+4105") image_path = path.join(dataset_path, "image.fits") image = al.Array2D.from_fits(file_path=image_path, hdu=0, pixel_scales=0.03) """ We need a `VectorField` to plot over the image. We make a simple example of a vector field below. """ vectors = al.VectorYX2DIrregular(vectors=[(1.0, 2.0), (2.0, 1.0)], grid=[(-1.0, 0.0), (-2.0, 0.0)]) """ To plot the vector field manually, we can pass it into a` Visuals2D` object. """ visuals_2d = aplt.Visuals2D(vectors=vectors) array_plotter = aplt.Array2DPlotter(array=image, visuals_2d=visuals_2d) array_plotter.figure_2d() """ We can customize the appearance of the vectors using the `VectorYXQuiver` matplotlib wrapper object which wraps the following method(s): https://matplotlib.org/3.3.2/api/_as_gen/matplotlib.pyplot.quiver.html """ quiver = aplt.VectorYXQuiver( headlength=1, pivot="tail", color="w", linewidth=10, units="width",
""" We can also use a `Pixelization` and `Regularization` (which combined create an `Inversion`. to reconstruct the source galaxy. we'll reconstruct the source on a 30 x 30 `Rectangular` source-plane `Pixelization`. """ pixelization = al.pix.Rectangular(shape=(30, 30)) """ A `Mapper` maps the source-pixels to image-pixels, as shown in the figure below. These mappings are used when reconstructing the source galaxy's light. """ mapper = pixelization.mapper_from(source_grid_slim=source_plane_grid) visuals_2d = aplt.Visuals2D(pix_indexes=[[312], [314], [350], [370]]) include_2d = aplt.Include2D(grid=True) mapper_plotter = aplt.MapperPlotter( mapper=mapper, visuals_2d=visuals_2d, include_2d=include_2d ) mapper_plotter.subplot_image_and_mapper(image=imaging.image) """ We can now use a `Mapper` to perform the `Inversion` and reconstruct the source galaxy's light. To perform this `Inverison` we must also input a `Regularization`, which is a prior on how much we smooth the source galaxy's light. Try increasing / decreasing the coefficient value to see what effect this has. """ regularization = al.reg.Constant(coefficient=1.0)
will be plotted in different colors. By default, PyAutoLens uses the same alternating colors for the critical_curves and critical_curves, so they appear the same color on image-plane and source-plane figures. """ critical_curves_plot = aplt.CriticalCurvesPlot(c=["r", "w"]) mat_plot_2d = aplt.MatPlot2D(critical_curves_plot=critical_curves_plot) tracer_plotter = aplt.TracerPlotter( tracer=tracer, grid=grid, include_2d=include_2d, mat_plot_2d=mat_plot_2d ) tracer_plotter.figures_2d(image=True) """ To plot critical_curves manually, we can pass them into a` Visuals2D` object. This is useful for plotting critical_curves on figures where they are not an internal property, like an `Array2D`. """ visuals_2d = aplt.Visuals2D(critical_curves=tracer.critical_curves_from_grid(grid=grid)) image = tracer.image_2d_from_grid(grid=grid) array_plotter = aplt.Array2DPlotter( array=image, mat_plot_2d=mat_plot_2d, visuals_2d=visuals_2d ) array_plotter.figure_2d() """ Finish. """
import autolens.plot as aplt """ First, lets load an example Hubble Space Telescope image of a real strong lens as an `Array2D`. """ dataset_path = path.join("dataset", "slacs", "slacs1430+4105") image_path = path.join(dataset_path, "image.fits") image = al.Array2D.from_fits(file_path=image_path, hdu=0, pixel_scales=0.03) """ We need a `VectorField` to plot over the image. We make a simple example of a vector field below. """ vector_field = al.VectorField2DIrregular(vectors=[(1.0, 2.0), (2.0, 1.0)], grid=[(-1.0, 0.0), (-2.0, 0.0)]) """ To plot the vector field manually, we can pass it into a` Visuals2D` object. """ visuals_2d = aplt.Visuals2D(vector_field=vector_field) array_plotter = aplt.Array2DPlotter(array=image, visuals_2d=visuals_2d) array_plotter.figure_2d() """ We can customize the appearance of the vectors using the `VectorFieldQuiver matplotlib wrapper object which wraps the following method(s): https://matplotlib.org/3.3.2/api/_as_gen/matplotlib.pyplot.quiver.html """ quiver = aplt.VectorFieldQuiver( headlength=1, pivot="tail", color="w", linewidth=10, units="width",
will be plotted in different colors. By default, PyAutoLens uses the same alternating colors for the caustics and caustics, so they appear the same color on image-plane and source-plane figures. """ caustics_plot = aplt.CausticsPlot(c=["r", "w"]) mat_plot_2d = aplt.MatPlot2D(caustics_plot=caustics_plot) tracer_plotter = aplt.TracerPlotter( tracer=tracer, grid=grid, include_2d=include_2d, mat_plot_2d=mat_plot_2d ) tracer_plotter.figures_2d(source_plane=True) """ To plot caustics manually, we can pass them into a` Visuals2D` object. This is useful for plotting caustics on figures where they are not an internal property, like an `Array2D`, as well as plotting them on image-plane images. """ visuals_2d = aplt.Visuals2D(caustics=tracer.caustics_from_grid(grid=grid)) image = tracer.image_2d_from_grid(grid=grid) array_plotter = aplt.Array2DPlotter( array=image, mat_plot_2d=mat_plot_2d, visuals_2d=visuals_2d ) array_plotter.figure_2d() """ Finish. """
When it comes to determining an appropriate mask for this image, the best approach is to set up a `Mask2D` and pass it to a `Imaging` mat_plot_2d. You can then check visually if the mask is an appropriate size or not. Below, we choose an inner radius that cuts into our lensed source galaxy - clearly this isn't a good mask. """ # %% mask = al.Mask2D.circular_annular( shape_2d=imaging.shape_2d, pixel_scales=imaging.pixel_scales, inner_radius=1.4, outer_radius=2.4, ) imaging_plotter = aplt.ImagingPlotter(imaging=imaging, visuals_2d=aplt.Visuals2D(mask=mask)) imaging_plotter.subplot_imaging() # %% """ So, lets decrease the inner radius to correct for this. """ # %% mask = al.Mask2D.circular_annular( shape_2d=imaging.shape_2d, pixel_scales=imaging.pixel_scales, inner_radius=0.6, outer_radius=2.4, )
""" pixel_scales = 0.1 """ First, load the `Imaging` dataset, so that the lens light centres can be plotted over the strong lens image. """ image = al.Array2D.from_fits(file_path=path.join(dataset_path, "image.fits"), pixel_scales=pixel_scales) """ Now, create a lens light centre, which is a Coordinate object of (y,x) values. """ light_centre = al.Grid2DIrregular(grid=[(0.0, 0.0)]) """ Now lets plot the image and lens light centre, so we can check that the centre overlaps the lens light. """ mat_plot_2d = aplt.MatPlot2D() visuals_2d = aplt.Visuals2D(light_profile_centres=light_centre) array_plotter = aplt.Array2DPlotter(array=image, visuals_2d=visuals_2d, mat_plot_2d=mat_plot_2d) array_plotter.figure_2d() """ Now we`re happy with the lens light centre(s), lets output them to the dataset folder of the lens, so that we can load them from a .json file in our pipelines! """ light_centre.output_to_json(file_path=path.join(dataset_path, "light_centre.json"), overwrite=True) """ The workspace also includes a GUI for drawing lens light centres, which can be found at `autolens_workspace/notebooks/preprocess/imaging/gui/light_centres.py`. This tools allows you `click` on the image where an
Before beginning chapter 2 of **HowToLens**, you should checkout the package `autolens_workspace/plot`. This provides a full API reference of every plotting option in **PyAutoLens**, allowing you to create your own fully customized figures of strong lenses with minimal effort! """ mat_plot_2d = aplt.MatPlot2D( title=aplt.Title(label="This is the title", color="r", fontsize=20), ylabel=aplt.YLabel(label="Label of Y", color="b", fontsize=5, position=(0.2, 0.5)), xlabel=aplt.XLabel(label="Label of X", color="g", fontsize=10), cmap=aplt.Cmap(cmap="cool", norm="linear"), ) include_2d = aplt.Include2D( origin=True, mask=True, border=True, light_profile_centres=True ) visuals_2d = aplt.Visuals2D(critical_curves=tracer.critical_curves_from(grid=fit.grid)) light_profile_plotter = aplt.LightProfilePlotter( light_profile=fit.tracer.source_plane.galaxies[0].bulge, grid=source_plane_grid, mat_plot_2d=mat_plot_2d, include_2d=include_2d, visuals_2d=visuals_2d, ) light_profile_plotter.set_title("Bulge Image") light_profile_plotter.figures_2d(image=True) """ And, we're done, not just with the tutorial, but the chapter! __Code Design__
We now pass the mapper to a `MapperPlotter` and call various `figure_*` methods to plot different attributes. """ mapper_plotter = aplt.MapperPlotter(mapper=mapper) mapper_plotter.figure_2d() """ __Subplots__ The `Mapper` can also be plotted with a subplot of its original image. """ mapper_plotter = aplt.MapperPlotter(mapper=mapper) mapper_plotter.subplot_image_and_mapper(image=imaging.image) """ The Indexes of `Mapper` plots can be highlighted to show how certain image pixels map to the source plane. """ visuals_2d = aplt.Visuals2D(indexes=[0, 1, 2, 3, 4], pix_indexes=[[10, 11], [12, 13, 14]]) mapper_plotter = aplt.MapperPlotter(mapper=mapper, visuals_2d=visuals_2d) mapper_plotter.subplot_image_and_mapper(image=imaging.image) """ __Include__ A `Mapper` contains the following attributes which can be plotted automatically via the `Include2D` object. """ include_2d = aplt.Include2D( origin=True, mask=True, border=True, mapper_data_pixelization_grid=True, mapper_source_pixelization_grid=True, mapper_source_grid_slim=True,
fit_imaging_plotter = aplt.FitImagingPlotter(fit=fit_imaging) fit_imaging_plotter.subplot_fit_imaging() """ We can also use a `Pixelization` and `Regularization` (which combined create an `Inversion`. to reconstruct the source galaxy. we'll reconstruct the source on a 30 x 30 `Rectangular` source-plane `Pixelization`. """ pixelization = al.pix.Rectangular(shape=(30, 30)) """ A `Mapper` maps the source-pixels to image-pixels, as shown in the figure below. These mappings are used when reconstructing the source galaxy's light. """ mapper = pixelization.mapper_from_grid_and_sparse_grid(grid=source_plane_grid) visuals_2d = aplt.Visuals2D(pixelization_indexes=[[312], [314], [350], [370]]) include_2d = aplt.Include2D(grid=True) mapper_plotter = aplt.MapperPlotter(mapper=mapper, visuals_2d=visuals_2d, include_2d=include_2d) mapper_plotter.subplot_image_and_mapper(image=imaging.image) """ We can now use a `Mapper` to perform the `Inversion` and reconstruct the source galaxy's light. To perform this `Inverison` we must also input a `Regularization`, which is a prior on how much we smooth the source galaxy's light. Try increasing / decreasing the coefficient value to see what effect this has. """ regularization = al.reg.Constant(coefficient=1.0)
""" Using the dataset path, load the data (image, noise-map, PSF) as an `Imaging` object from .fits files. """ imaging = al.Imaging.from_fits( image_path=path.join(dataset_path, "image.fits"), psf_path=path.join(dataset_path, "psf.fits"), noise_map_path=path.join(dataset_path, "noise_map.fits"), pixel_scales=pixel_scales, ) mask = al.Mask2D.circular( shape_native=imaging.shape_native, pixel_scales=pixel_scales, radius=3.0 ) imaging_plotter = aplt.ImagingPlotter( imaging=imaging, visuals_2d=aplt.Visuals2D(mask=mask) ) imaging_plotter.subplot_imaging() """ __Settings__ The `SettingsPhaseImaging` describe how the model is fitted to the data in the log likelihood function. These settings are used and described throughout the `autolens_workspace/examples/model` example scripts, with a complete description of all settings given in `autolens_workspace/examples/model/customize/settings.py`. The settings chosen here are applied to all phases in the pipeline. """ settings_masked_imaging = al.SettingsMaskedImaging(grid_class=al.Grid2D, sub_size=2)
By specifying two colors to the `MassProfileCentresScatter` object the mass profile centres of each plane are plotted in different colors. """ mass_profile_centres_scatter = aplt.MassProfileCentresScatter(c=["r", "w"], s=150) mat_plot_2d = aplt.MatPlot2D(mass_profile_centres_scatter=mass_profile_centres_scatter) tracer_plotter = aplt.TracerPlotter( tracer=tracer, grid=grid, include_2d=include_2d, mat_plot_2d=mat_plot_2d ) tracer_plotter.figures_2d(image=True) """ To plot the mass profile centres manually, we can pass them into a` Visuals2D` object. This is useful for plotting the centres on figures where they are not an internal property, like an `Array2D`. """ mass_profile_centres = tracer.extract_attribute( cls=al.mp.MassProfile, attr_name="centre" ) visuals_2d = aplt.Visuals2D(mass_profile_centres=mass_profile_centres) image = tracer.image_2d_from(grid=grid) array_plotter = aplt.Array2DPlotter( array=image, mat_plot_2d=mat_plot_2d, visuals_2d=visuals_2d ) array_plotter.figure_2d() """ Finish. """
def test__2d__via_tracer(tracer_x2_plane_7x7, grid_2d_7x7): visuals_2d = aplt.Visuals2D(vectors=2) include_2d = aplt.Include2D( origin=True, border=True, light_profile_centres=True, mass_profile_centres=True, critical_curves=True, ) get_visuals = GetVisuals2D(include=include_2d, visuals=visuals_2d) visuals_2d_via = get_visuals.via_tracer_from(tracer=tracer_x2_plane_7x7, grid=grid_2d_7x7, plane_index=0) assert visuals_2d_via.origin.in_list == [(0.0, 0.0)] assert (visuals_2d_via.border == grid_2d_7x7.mask.border_grid_sub_1.binned ).all() assert visuals_2d_via.light_profile_centres.in_list == [ tracer_x2_plane_7x7.galaxies[1].light_profile_0.centre ] assert visuals_2d_via.mass_profile_centres.in_list == [ tracer_x2_plane_7x7.galaxies[0].mass_profile_0.centre ] assert (visuals_2d_via.critical_curves[0] == tracer_x2_plane_7x7. critical_curves_from(grid=grid_2d_7x7)[0]).all() assert visuals_2d_via.vectors == 2 include_2d = aplt.Include2D( origin=True, border=True, light_profile_centres=True, mass_profile_centres=True, caustics=True, ) get_visuals = GetVisuals2D(include=include_2d, visuals=visuals_2d) visuals_2d_via = get_visuals.via_tracer_from(tracer=tracer_x2_plane_7x7, grid=grid_2d_7x7, plane_index=1) assert visuals_2d_via.origin.in_list == [(0.0, 0.0)] traced_border = tracer_x2_plane_7x7.traced_grid_2d_list_from( grid=grid_2d_7x7.mask.border_grid_sub_1.binned)[1] assert (visuals_2d_via.border == traced_border).all() assert visuals_2d_via.light_profile_centres.in_list == [ tracer_x2_plane_7x7.galaxies[1].light_profile_0.centre ] assert visuals_2d_via.mass_profile_centres is None assert (visuals_2d_via.caustics[0] == tracer_x2_plane_7x7.caustics_from( grid=grid_2d_7x7)[0]).all() include_2d = aplt.Include2D( origin=False, border=False, light_profile_centres=False, mass_profile_centres=False, critical_curves=False, ) get_visuals = GetVisuals2D(include=include_2d, visuals=visuals_2d) visuals_2d_via = get_visuals.via_tracer_from(tracer=tracer_x2_plane_7x7, grid=grid_2d_7x7, plane_index=0) assert visuals_2d_via.origin is None assert visuals_2d_via.border is None assert visuals_2d_via.light_profile_centres is None assert visuals_2d_via.mass_profile_centres is None assert visuals_2d_via.critical_curves is None assert visuals_2d_via.vectors == 2
image_path=path.join(dataset_path, "image.fits"), noise_map_path=path.join(dataset_path, "noise_map.fits"), psf_path=path.join(dataset_path, "psf.fits"), pixel_scales=0.1, ) """ Lets create an annular mask which traces the stongly lensed source's ring of light. """ mask = al.Mask2D.circular_annular( shape_native=imaging.shape_native, pixel_scales=imaging.pixel_scales, inner_radius=0.5, outer_radius=2.8, ) visuals_2d = aplt.Visuals2D(mask=mask) imaging_plotter = aplt.ImagingPlotter(imaging=imaging, visuals_2d=visuals_2d) imaging_plotter.figures_2d(image=True) """ We now create the masked source-plane grid via the tracer, as we did in the previous tutorial. """ imaging = imaging.apply_mask(mask=mask) lens_galaxy = al.Galaxy( redshift=0.5, mass=al.mp.EllIsothermal( centre=(0.0, 0.0), einstein_radius=1.6, elliptical_comps=al.convert.elliptical_comps_from(axis_ratio=0.9, angle=45.0),
# mask = al.Mask2D.elliptical_annular( # shape_native=image.shape_native, # pixel_scales=image.pixel_scales, # inner_major_axis_radius=0.5, # inner_axis_ratio=0.7, # inner_phi=45.0, # outer_major_axis_radius=0.5, # outer_axis_ratio=0.7, # outer_phi=45.0, # centre=(0.0, 0.0), # ) """ Now lets plot the image and mask, so we can check that the mask includes the regions of the image we want. """ visuals_2d = aplt.Visuals2D(mask=mask) array_plotter = aplt.Array2DPlotter(array=image, visuals_2d=visuals_2d) array_plotter.figure_2d() """ Now we`re happy with the mask, lets output it to the dataset folder of the lens, so that we can load it from a .fits file in our pipelines! """ mask.output_to_fits(file_path=path.join(dataset_path, "mask.fits"), overwrite=True) """ The workspace also includes a GUI for drawing a mask, which can be found at `autolens_workspace/notebooks/preprocess/imaging/gui/mask.py`. This tools allows you to draw the mask via a `spray paint` mouse icon, such that you can draw irregular masks more tailored to the source's light. """
imaging = al.Imaging.from_fits( image_path=path.join(dataset_path, "image.fits"), noise_map_path=path.join(dataset_path, "noise_map.fits"), psf_path=path.join(dataset_path, "psf.fits"), pixel_scales=0.1, ) mask = al.Mask2D.circular( shape_native=imaging.shape_native, pixel_scales=imaging.pixel_scales, sub_size=2, radius=3.0, ) imaging_plotter = aplt.ImagingPlotter(imaging=imaging, visuals_2d=aplt.Visuals2D(mask=mask)) imaging_plotter.subplot_imaging() """ The lines of code below do everything we're used to, that is, setup an image, mask it, trace it via a tracer, setup the rectangular mapper, etc. """ lens_galaxy = al.Galaxy( redshift=0.5, mass=al.mp.EllIsothermal( centre=(0.0, 0.0), einstein_radius=1.6, elliptical_comps=al.convert.elliptical_comps_from(axis_ratio=0.9, angle=45.0), ), shear=al.mp.ExternalShear(elliptical_comps=(0.05, 0.05)), )
__Mappings__ Lets plot the image and source planes next to one another and highlight specific points on both. The coloring of the highlighted points therefore shows how specific image pixels **map** to the source-plane (and visa versa). This is the first time we have used the `Visuals2D` object, which allows the appearance of **PyAutoLens** figures to be customized. We'll see this object crop up throughout the **HowToLens** lectures, and a full description of all of its options is provided in the `autolens_workspace/plot` package. Below, we input integer `indexes` that highlight the image-pixels that correspond to those indexes in a different color. We highlight indexes running from 0 -> 50, which appear over the top row of the image-plane grid, alongside numerous other indexes. """ visuals_2d = aplt.Visuals2D(indexes=[ range(0, 50), range(500, 550), [1350, 1450, 1550, 1650, 1750, 1850, 1950, 2050, 2150, 2250], [6250, 8550, 8450, 8350, 8250, 8150, 8050, 7950, 7850, 7750], ]) mat_plot_2d = aplt.MatPlot2D(title=aplt.Title(label="Image-plane Grid")) plane_plotter = aplt.PlanePlotter( plane=image_plane, grid=image_plane_grid, mat_plot_2d=mat_plot_2d, visuals_2d=visuals_2d, ) plane_plotter.figures_2d(plane_grid=True) mat_plot_2d = aplt.MatPlot2D(title=aplt.Title(label="Source-plane Grid"))
import autolens as al import autolens.plot as aplt """ First, lets load an example Hubble Space Telescope image of a real strong lens as an `Array2D`. """ dataset_path = path.join("dataset", "slacs", "slacs1430+4105") image_path = path.join(dataset_path, "image.fits") image = al.Array2D.from_fits(file_path=image_path, hdu=0, pixel_scales=0.03) """ We next need the 2D `Grid2D` we overlay. We'll create a uniform grid at a coarser resolution than our dataset. """ grid = al.Grid2D.uniform(shape_native=(30, 30), pixel_scales=0.1) """ We input this `Grid2D` into the `Visuals2D` object, which plots it over the figure. """ visuals_2d = aplt.Visuals2D(grid=grid) """ We now plot the image with the grid overlaid. """ array_plotter = aplt.Array2DPlotter(array=image, visuals_2d=visuals_2d) array_plotter.figure_2d() """ We customize the grid's appearance using the `GridScatter` `matplotlib wrapper object which wraps the following method(s): https://matplotlib.org/3.3.2/api/_as_gen/matplotlib.pyplot.scatter.html """ grid_scatter = aplt.GridScatter(c="r", marker=".", s=1) mat_plot_2d = aplt.MatPlot2D(grid_scatter=grid_scatter) array_plotter = aplt.Array2DPlotter(array=image,