diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies.md b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies.md index 9b3a8ba..e0caf45 100644 --- a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies.md +++ b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies.md @@ -58,6 +58,8 @@ __Contents__ - **Geometry:** The above grid is centered on the origin (0.0", 0.0"). - **Light Profiles:** Galaxies are collections of stars, gas, dust, and other astronomical objects that emit light. - **One Dimension Projection:** We often want to calculative 1D quantities of a light profile, for example to plot how its light. +- **Galaxies:** Galaxies are collections of light profiles that represent a galaxy's luminous emission. +- **Units:** By assuming a redshift for a galaxy we can convert its quantities from arcseconds to kiloparsecs. ```python @@ -74,6 +76,12 @@ import autolens as al import autolens.plot as aplt ``` + 2026-07-11 18:13:08,002 - matplotlib.font_manager - INFO - Failed to extract font properties from /usr/share/fonts/truetype/noto/NotoColorEmoji.ttf: Can not load face (unknown file format; error code 0x2) + + + 2026-07-11 18:13:08,198 - matplotlib.font_manager - INFO - generated new fontManager + + Working Directory has been set to `HowToLens` @@ -566,10 +574,362 @@ plt.close() Since galaxy light distributions often cover a wide range of values, they are typically better visualized on a log10 scale. This approach helps highlight details in the faint outskirts of a light profile. -The `plot_array`/`subplot_\*` object has a `use_log10` option that applies this transformation automatically. Below, you can see +The `plot_array`/`subplot_\*` object has a `use_log10` option that applies this transformation automatically. Below, you can see that the image plotted in log10 space reveals more details. +```python +aplt.plot_array( + array=sersic_light_profile.image_2d_from(grid=grid), + title="Sersic Image", + use_log10=True, +) +``` + + + +![png](tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_45_0.png) + + + +__Galaxies__ + +Now, let's introduce `Galaxy` objects, which are a key component in **PyAutoLens**. + +A light profile represents a single feature of a galaxy, such as its bulge or disk. To model a complete galaxy, +we combine multiple light profiles into a `Galaxy` object. This allows us to create images that include different +components of a galaxy. + +In addition to light profiles, a `Galaxy` has a `redshift`, which indicates how far away it is from Earth. The redshift +is essential for performing unit conversions using cosmological calculations, such as converting arc-seconds into +kiloparsecs. (A kiloparsec is a distance unit in astronomy, equal to about 3.26 million light-years.) + +Redshifts are especially important in strong lensing, where the foreground lens galaxy and background source galaxy +lie at two different redshifts. We are not yet performing any lensing calculations in this tutorial, so for now we +simply use a single galaxy to build up intuition for the `Galaxy` object. + +Let's start by creating a galaxy with two `Sersic` light profiles, which we will consider to represent a bulge and +disk component of the galaxy, the two most important structures seen in galaxies. + + +```python +bulge = al.lp.Sersic( + centre=(0.0, 0.0), + ell_comps=(0.0, 0.111111), + intensity=1.0, + effective_radius=1.0, + sersic_index=2.5, +) + +disk = al.lp.Sersic( + centre=(0.0, 0.0), + ell_comps=(0.0, 0.3), + intensity=0.3, + effective_radius=3.0, + sersic_index=1.0, +) + +galaxy = al.Galaxy(redshift=0.5, bulge=bulge, disk=disk) + +print(galaxy) +``` + + Redshift: 0.5 + Light Profiles: + Sersic + centre: (0.0, 0.0) + ell_comps: (0.0, 0.111111) + intensity: 1.0 + effective_radius: 1.0 + sersic_index: 2.5 + Sersic + centre: (0.0, 0.0) + ell_comps: (0.0, 0.3) + intensity: 0.3 + effective_radius: 3.0 + sersic_index: 1.0 + + +We can pass a 2D grid to a light profile to compute its image using the `image_2d_from` method. + +The same approach works for a `Galaxy` object: + + +```python +image = galaxy.image_2d_from(grid=grid) + +print("Intensity of `Grid2D` pixel 0:") +print(image.native[0, 0]) +print("Intensity of `Grid2D` pixel 1:") +print(image.native[0, 1]) +print("Intensity of `Grid2D` pixel 2:") +print(image.native[0, 2]) +print("...") +``` + + Intensity of `Grid2D` pixel 0: + 0.024894917164848044 + Intensity of `Grid2D` pixel 1: + 0.025428546280541572 + Intensity of `Grid2D` pixel 2: + 0.02596640780160061 + ... + + +We can plot the galaxy's image, just like how we did for a light profile. + + +```python +aplt.plot_array(array=galaxy.image_2d_from(grid=grid), title="Galaxy Bulge+Disk Image") +``` + + + +![png](tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_51_0.png) + + + +The bulge dominates the center of the image, and is pretty much the only luminous emission we can see on a linear +scale. The disk's emission is present, but it is much fainter and spread over a larger area. + +We can confirm this using the `subplot_galaxy_light_profiles` method, which plots each individual light profile +separately. + + +```python +aplt.subplot_galaxy_light_profiles(galaxy=galaxy, grid=grid) +``` + + + +![png](tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_53_0.png) + + + +Because galaxy light distributions often follow a log10 pattern, plotting in log10 space helps reveal details in the +outskirts of the light profile, in this case the emission of the disk. + +This is especially helpful to separate the bulge and disk profiles, which have different intensities and sizes. + + +```python +aplt.plot_array( + array=galaxy.image_2d_from(grid=grid), + title="Galaxy Bulge+Disk Image", + use_log10=True, +) +``` + + + +![png](tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_55_0.png) + + + +Using the tools above, we can visualize each light profile's contribution in 1D. + +1D plots show the intensity of the light profile as a function of distance from the profile's center. The bulge +and disk profiles in this example share the same `centre`, meaning that plotting them together on the same 1D plot +shows how they vary relative to one another. + +If the `centre` of the profiles were different, when you make the 1D plot you would need to decide whether to plot the +profiles offset from one another or plot them both from zero. + + +```python +grid_2d_projected = grid.grid_2d_radial_projected_from( + centre=galaxy.bulge.centre, angle=galaxy.bulge.angle() +) +bulge_image_1d = galaxy.bulge.image_2d_from(grid=grid_2d_projected) + +grid_2d_projected = grid.grid_2d_radial_projected_from( + centre=galaxy.disk.centre, angle=galaxy.disk.angle() +) +disk_image_1d = galaxy.disk.image_2d_from(grid=grid_2d_projected) + +plt.plot(grid_2d_projected[:, 1], bulge_image_1d, label="Bulge") +plt.plot(grid_2d_projected[:, 1], disk_image_1d, label="Disk") +plt.xlabel("Radius (arcseconds)") +plt.ylabel("Luminosity") +plt.legend() +plt.show() +plt.close() +``` + + + +![png](tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_57_0.png) + + + +We can group multiple galaxies at the same redshift into a `Galaxies` object, which is created from a list of +individual galaxies. + +In a strong lens, we ultimately group together a foreground lens galaxy and a background source galaxy. For now, we +simply create a second galaxy and combine it with the original galaxy into a `Galaxies` object, to see how the light +of multiple galaxies is represented. + + +```python +extra_galaxy = al.Galaxy( + redshift=0.5, + bulge=al.lp.Sersic( + centre=(0.2, 0.3), + ell_comps=(0.0, 0.111111), + intensity=1.0, + effective_radius=1.0, + sersic_index=2.5, + ), +) + +galaxies = al.Galaxies(galaxies=[galaxy, extra_galaxy]) +``` + +The `Galaxies` object has similar methods to those for light profiles and individual galaxies. + +For example, `image_2d_from` sums the images of all the galaxies. + + +```python +image = galaxies.image_2d_from(grid=grid) +``` + +We can plot the combined image of all the galaxies, just like with other plotters. + + +```python +aplt.plot_array(array=galaxies.image_2d_from(grid=grid), title="Image") +``` + + + +![png](tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_63_0.png) + + + +A subplot of each individual galaxy image can also be created. + + +```python +aplt.subplot_galaxies(galaxies=galaxies, grid=grid) +``` + + + +![png](tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_65_0.png) + + + +Because galaxy light distributions often follow a log10 pattern, plotting in log10 space helps reveal details in the +outskirts of the light profile. + +This is especially helpful when visualizing how multiple galaxies overlap. + + +```python +aplt.plot_array(array=galaxies.image_2d_from(grid=grid), title="Image", use_log10=True) +``` + + + +![png](tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_67_0.png) + + + +__Units__ + +Earlier, we mentioned that a galaxy's `redshift` allows us to convert between arcseconds and kiloparsecs. + +A redshift measures how much a galaxy's light is stretched by the Universe's expansion. A higher redshift means the +galaxy is further away, and its light has been stretched more. By knowing a galaxy's redshift, we can convert angular +distances (like arcseconds) to physical distances (like kiloparsecs). + +To perform this conversion, we use a cosmological model that describes the Universe's expansion. Below, we use +the `Planck15` cosmology, which is based on observations from the Planck satellite. + + +```python +cosmology = al.cosmo.Planck15() + +kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=galaxy.redshift) + +print("Kiloparsecs per Arcsecond:") +print(kpc_per_arcsec) +``` + + Kiloparsecs per Arcsecond: + 6.288247910157764 + + +This `kpc_per_arcsec` can be used as a conversion factor between arcseconds and kiloparsecs when plotting images of +galaxies. + +We compute this value and plot the image, which by default is shown in units of arcseconds. + + +```python +aplt.plot_array(array=galaxy.image_2d_from(grid=grid), title="Image") +``` + + + +![png](tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_71_0.png) + + + +__Wrap Up__ + +In this tutorial, you've learnt the basic quantities used to describe the galaxies that make up a strong lens, before +we introduce any lensing calculations. + +Let's summarise what we've covered: + +- **Grids**: A grid is a set of 2D $(y,x)$ coordinates that represent the positions where we measure the light of a +galaxy. + +- **Geometry**: We showed how to shift, rotate, and convert grids to elliptical coordinates. + +- **Light Profiles**: Light profiles are analytic functions that describe how a galaxy's light is distributed in +space. We used the `Sersic` profile to create images of galaxies. + +- **Galaxies**: Galaxies are collections of light profiles. We created galaxies with multiple light profiles, combined +them into a `Galaxies` object, and visualized their images. + +- **Units**: By assuming redshifts for galaxies we can convert their quantities from arcseconds to physical units like +kiloparsecs. + +In the next tutorial, we'll introduce the mass of a galaxy and perform our first lensing calculation, whereby the +light of a background source galaxy is deflected by the mass of a foreground lens galaxy. + +__Advanced Topics__ + +The following advanced topics are not important for a new user learning the software for the first time. However, +once you are an expert user, the following guides and concepts are important for doing accurate strong lens analysis, +and thus may be things you want to commit to memory as future references. + +__Other Unit Conversion__ + +Above, we used a redshift to convert between arcseconds and kiloparsecs. This is just one example of a unit conversion +that can be performed using a galaxy's redshift. + +There are many other unit conversions that can be performed, such as converting the units of a galaxy's image to what +Astronomers call an AB magnitude system, which is a system used to measure the brightness of galaxies. + +The `autolens_workspace/*/guides/units` module contains many examples of unit conversions and how to use them, +but they will not be covered in the *HowToLens* tutorials. + +__Over Sampling__ + +Over sampling is a numerical technique where the images of light profiles and galaxies are evaluated +on a higher resolution grid than the image data to ensure the calculation is accurate. + +For a new user, the details of over-sampling are not important, therefore just be aware that all calculations use an +adaptive over sampling scheme with high accuracy across all use cases. + +Once you are more experienced, you should read up on over-sampling in more detail via +the `autolens_workspace/*/guides/over_sampling.ipynb` notebook. + + ```python ``` diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_45_0.png b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_45_0.png new file mode 100644 index 0000000..1578cbc Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_45_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_51_0.png b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_51_0.png new file mode 100644 index 0000000..1c45883 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_51_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_53_0.png b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_53_0.png new file mode 100644 index 0000000..0acaae2 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_53_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_55_0.png b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_55_0.png new file mode 100644 index 0000000..ae02510 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_55_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_57_0.png b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_57_0.png new file mode 100644 index 0000000..c4da721 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_57_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_63_0.png b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_63_0.png new file mode 100644 index 0000000..394fd23 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_63_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_65_0.png b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_65_0.png new file mode 100644 index 0000000..140ae5b Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_65_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_67_0.png b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_67_0.png new file mode 100644 index 0000000..29c3a75 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_67_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_71_0.png b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_71_0.png new file mode 100644 index 0000000..9ca518c Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_1_grids_and_galaxies_files/tutorial_1_grids_and_galaxies_71_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing.md b/markdown/chapter_1_introduction/tutorial_2_ray_tracing.md index bbe624c..a9cc3c7 100644 --- a/markdown/chapter_1_introduction/tutorial_2_ray_tracing.md +++ b/markdown/chapter_1_introduction/tutorial_2_ray_tracing.md @@ -57,12 +57,17 @@ construct realistic lens and source galaxies. - **Tracer**: Introduce the `Tracer` object, which automates the ray-tracing process and allows us to compute images of the entire lens system. -- **Mappings**: Visualize how image pixels map to the source plane and vice versa using the `lines=`/`positions=` overlays object. +- **Mappings**: Visualize how coordinates in the image-plane map to the source-plane by plotting the ray-traced grids. __Contents__ - **Grid:** In the previous tutorial, we created 2D grids of (y,x) coordinates and showed how shifting and. - **Mass Profiles:** To perform lensing calculations, we use mass profiles available in the `mass_profile` module. +- **Ray Tracing Grids:** The lens equation uses deflection angles to map image-plane coordinates to the source-plane. +- **Ray Tracing Images:** Evaluating a source's light on the ray-traced grid produces its lensed image. +- **Galaxies:** A `Galaxy` can contain both light and mass profiles, forming realistic lens and source galaxies. +- **Tracer:** The `Tracer` object automates ray-tracing for a system of galaxies at different redshifts. +- **Mappings:** Every image-plane coordinate maps to a source-plane coordinate via the lens equation. ```python @@ -293,6 +298,275 @@ plt.close() The **convergence** and **potential** can be better understood when plotted in logarithmic space: +```python +aplt.plot_array( + array=sis_mass_profile.convergence_2d_from(grid=image_plane_grid), + title="Convergence in Log10 Space", + use_log10=True, +) +aplt.plot_array( + array=sis_mass_profile.potential_2d_from(grid=image_plane_grid), + title="Potential in Log10 Space", + use_log10=True, +) +``` + + + +![png](tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_23_0.png) + + + + + +![png](tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_23_1.png) + + + +__Ray Tracing Grids__ + +We now have all the tools we need to perform our first ray-tracing calculation. + +Ray tracing uses a mass profile's deflection angles to map coordinates from the image-plane (where we observe the +lensed source) to the source-plane (where the source truly is). This mapping is described by the **lens equation**: + +$\beta = \theta - \alpha(\theta)$ + +where $\theta$ are the image-plane coordinates, $\alpha(\theta)$ are the deflection angles of the mass profile, and +$\beta$ are the corresponding source-plane coordinates. + +We compute the deflection angles of our mass profile on the `image_plane_grid`, and then use the grid's +`grid_2d_via_deflection_grid_from` method to subtract them and produce the ray-traced `source_plane_grid`. + + +```python +deflections = sis_mass_profile.deflections_yx_2d_from(grid=image_plane_grid) + +source_plane_grid = image_plane_grid.grid_2d_via_deflection_grid_from( + deflection_grid=deflections +) +``` + +Let's plot the image-plane grid and the ray-traced source-plane grid. + +The image-plane grid is uniform, but the source-plane grid is distorted. This distortion is caused by the mass +profile's deflection angles, which bend the light rays as they pass the lens galaxy. The coordinates near the +center of the mass are deflected the most. + + +```python +aplt.plot_grid(grid=image_plane_grid, title="Image Plane Grid") +aplt.plot_grid(grid=source_plane_grid, title="Source Plane Grid (Ray Traced)") +``` + + + +![png](tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_27_0.png) + + + + + +![png](tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_27_1.png) + + + +__Ray Tracing Images__ + +The source-plane grid tells us where each image-plane coordinate lands in the source-plane after being deflected. + +To compute the lensed image of a source galaxy, we place a light profile in the source-plane and evaluate its light +on the ray-traced `source_plane_grid`. Because many image-plane coordinates map to the same region of the +source-plane, the source appears multiply imaged, forming arcs or a complete Einstein ring. + +Let's create a source light profile and compute its lensed image. + + +```python +source_light_profile = al.lp.ExponentialCore( + centre=(0.1, 0.1), + ell_comps=(0.0, 0.1), + intensity=0.1, + effective_radius=0.2, +) + +lensed_image = source_light_profile.image_2d_from(grid=source_plane_grid) +``` + +When we plot this image, the source's light appears as a strongly lensed Einstein ring. + +This is the **image-plane image** or **observed image** we discussed at the start of the tutorial: the appearance +of the source *after* its light has been deflected by the lens galaxy's mass. + +*Exercise*: Try changing the `centre` of the source light profile. Observe how moving the source relative to the +lens galaxy changes the lensed image from a ring into arcs or multiple images. + + +```python +aplt.plot_array(array=lensed_image, title="Lensed Source Image") +``` + + + +![png](tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_31_0.png) + + + +__Galaxies__ + +In the previous tutorial we saw that a `Galaxy` can contain one or more light profiles. A `Galaxy` can also contain +mass profiles, and can contain both at the same time. + +This lets us construct realistic lens and source galaxies: + +- The **lens galaxy** has a mass profile (which deflects light) and typically a light profile (its own emission). +- The **source galaxy** has a light profile (the light we see lensed), and is at a higher redshift. + + +```python +lens_galaxy = al.Galaxy( + redshift=0.5, + mass=sis_mass_profile, +) + +source_galaxy = al.Galaxy( + redshift=1.0, + bulge=source_light_profile, +) + +print(lens_galaxy) +print(source_galaxy) +``` + + Redshift: 0.5 + Mass Profiles: + IsothermalSph + centre: (0.0, 0.0) + ell_comps: (0.0, 0.0) + einstein_radius: 1.6 + slope: 2.0 + core_radius: 0.0 + Redshift: 1.0 + Light Profiles: + ExponentialCore + centre: (0.1, 0.1) + ell_comps: (0.0, 0.1) + intensity: 0.1 + effective_radius: 0.2 + sersic_index: 1.0 + radius_break: 0.01 + alpha: 3.0 + gamma: 0.25 + + +__Tracer__ + +Performing the ray-tracing calculation manually, as we did above, becomes cumbersome once we have multiple galaxies +at multiple redshifts. + +The `Tracer` object automates the entire ray-tracing process. We create it from a list of galaxies, ordered by their +redshift, and it uses their redshifts and a cosmological model to set up the strong lens system. + + +```python +tracer = al.Tracer(galaxies=[lens_galaxy, source_galaxy]) +``` + +The `Tracer` has an `image_2d_from` method, just like light profiles and galaxies. It performs all the ray-tracing +for us and returns the image of the entire strong lens system. + +This produces the same lensed Einstein ring we computed manually above, but in a single line of code. + + +```python +image = tracer.image_2d_from(grid=image_plane_grid) + +aplt.plot_array(array=image, title="Image of Strong Lens System via Tracer") +``` + + + +![png](tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_37_0.png) + + + +The `subplot_tracer` method plots a subplot of the most important quantities of the strong lens system, including +its image, convergence, potential and deflection angles. + + +```python +aplt.subplot_tracer(tracer=tracer, grid=image_plane_grid) +``` + + + +![png](tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_39_0.png) + + + +__Mappings__ + +The `Tracer` also gives us access to the grids of every plane in the strong lens system, via the +`traced_grid_2d_list_from` method. + +This returns a list, where the first entry is the image-plane grid and the second entry is the ray-traced +source-plane grid. These are the same two grids we computed manually earlier, but now produced by the tracer. + + +```python +traced_grid_list = tracer.traced_grid_2d_list_from(grid=image_plane_grid) + +image_plane_grid_traced = traced_grid_list[0] +source_plane_grid_traced = traced_grid_list[1] +``` + +By plotting the image-plane and source-plane grids together, we can visualize the **mappings** between them. + +Every coordinate in the image-plane maps to a coordinate in the source-plane via the lens equation. This mapping is +the heart of strong lens modeling: to fit a lens, we ray-trace the image-plane grid to the source-plane, evaluate +the source's light there, and compare the resulting lensed image to the observed data. + + +```python +aplt.plot_grid(grid=image_plane_grid_traced, title="Image Plane Grid") +aplt.plot_grid(grid=source_plane_grid_traced, title="Source Plane Grid") +``` + + + +![png](tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_43_0.png) + + + + + +![png](tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_43_1.png) + + + +__Wrap Up__ + +In this tutorial, you performed your first lensing calculations. Let's summarise what we've learnt: + +- **Mass Profiles**: Mass profiles are analytic functions that describe the mass distribution of a galaxy. They are +used to compute deflection angles, as well as the convergence and gravitational potential. + +- **Ray Tracing Grids**: The lens equation, $\beta = \theta - \alpha(\theta)$, uses deflection angles to map +image-plane coordinates to the source-plane, producing a distorted ray-traced grid. + +- **Ray Tracing Images**: By evaluating a source galaxy's light on the ray-traced source-plane grid, we compute the +lensed image of the source, which appears as arcs or an Einstein ring. + +- **Galaxies**: A `Galaxy` can contain both light and mass profiles, allowing us to construct realistic lens and +source galaxies. + +- **Tracer**: The `Tracer` object automates the ray-tracing process for a system of galaxies at different redshifts, +computing the image of the entire strong lens system in a single line of code. + +In the next tutorial, we'll extend these ideas to more complex mass and light distributions, building towards the +realistic strong lens systems we observe in real data. + + ```python ``` diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_23_0.png b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_23_0.png new file mode 100644 index 0000000..db585b8 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_23_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_23_1.png b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_23_1.png new file mode 100644 index 0000000..74ecd97 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_23_1.png differ diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_27_0.png b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_27_0.png new file mode 100644 index 0000000..71bc1d4 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_27_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_27_1.png b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_27_1.png new file mode 100644 index 0000000..f1c6c59 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_27_1.png differ diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_31_0.png b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_31_0.png new file mode 100644 index 0000000..b48adc0 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_31_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_37_0.png b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_37_0.png new file mode 100644 index 0000000..ebb5cf0 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_37_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_39_0.png b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_39_0.png new file mode 100644 index 0000000..96c4be1 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_39_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_43_0.png b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_43_0.png new file mode 100644 index 0000000..71bc1d4 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_43_0.png differ diff --git a/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_43_1.png b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_43_1.png new file mode 100644 index 0000000..c3c2b91 Binary files /dev/null and b/markdown/chapter_1_introduction/tutorial_2_ray_tracing_files/tutorial_2_ray_tracing_43_1.png differ