def test_subplot_fit_imaging_is_output(masked_imaging_fit_x2_plane_7x7,
                                       include_2d_all, plot_path, plot_patch):

    fit_imaging_plotter = aplt.FitImagingPlotter(
        fit=masked_imaging_fit_x2_plane_7x7,
        include_2d=include_2d_all,
        mat_plot_2d=aplt.MatPlot2D(
            output=aplt.Output(plot_path, format="png")),
    )

    fit_imaging_plotter.subplot_fit_imaging()
    assert path.join(plot_path, "subplot_fit_imaging.png") in plot_patch.paths
def test__fit_quantities_are_output(masked_imaging_fit_x2_plane_7x7,
                                    include_2d_all, plot_path, plot_patch):

    fit_imaging_plotter = aplt.FitImagingPlotter(
        fit=masked_imaging_fit_x2_plane_7x7,
        include_2d=include_2d_all,
        mat_plot_2d=aplt.MatPlot2D(
            output=aplt.Output(path=plot_path, format="png")),
    )

    fit_imaging_plotter.figures(
        image=True,
        noise_map=True,
        signal_to_noise_map=True,
        model_image=True,
        residual_map=True,
        normalized_residual_map=True,
        chi_squared_map=True,
    )

    assert path.join(plot_path, "image.png") in plot_patch.paths
    assert path.join(plot_path, "noise_map.png") in plot_patch.paths
    assert path.join(plot_path, "signal_to_noise_map.png") in plot_patch.paths
    assert path.join(plot_path, "model_image.png") in plot_patch.paths
    assert path.join(plot_path, "residual_map.png") in plot_patch.paths
    assert path.join(plot_path,
                     "normalized_residual_map.png") in plot_patch.paths
    assert path.join(plot_path, "chi_squared_map.png") in plot_patch.paths

    plot_patch.paths = []

    fit_imaging_plotter.figures(
        image=True,
        noise_map=False,
        signal_to_noise_map=False,
        model_image=True,
        chi_squared_map=True,
    )

    assert path.join(plot_path, "image.png") in plot_patch.paths
    assert path.join(plot_path, "noise_map.png") not in plot_patch.paths
    assert path.join(plot_path,
                     "signal_to_noise_map.png") not in plot_patch.paths
    assert path.join(plot_path, "model_image.png") in plot_patch.paths
    assert path.join(plot_path, "residual_map.png") not in plot_patch.paths
    assert path.join(plot_path,
                     "normalized_residual_map.png") not in plot_patch.paths
    assert path.join(plot_path, "chi_squared_map.png") in plot_patch.paths
def test__figures_of_plane(masked_imaging_fit_x2_plane_7x7, include_2d_all,
                           plot_path, plot_patch):

    fit_imaging_plotter = aplt.FitImagingPlotter(
        fit=masked_imaging_fit_x2_plane_7x7,
        include_2d=include_2d_all,
        mat_plot_2d=aplt.MatPlot2D(
            output=aplt.Output(path=plot_path, format="png")),
    )

    fit_imaging_plotter.figures_of_planes(subtracted_image=True,
                                          model_image=True,
                                          plane_image=True)

    assert path.join(plot_path,
                     "subtracted_image_of_plane_0.png") in plot_patch.paths
    assert path.join(plot_path,
                     "subtracted_image_of_plane_1.png") in plot_patch.paths
    assert path.join(plot_path,
                     "model_image_of_plane_0.png") in plot_patch.paths
    assert path.join(plot_path,
                     "model_image_of_plane_1.png") in plot_patch.paths
    assert path.join(plot_path,
                     "plane_image_of_plane_0.png") in plot_patch.paths
    assert path.join(plot_path,
                     "plane_image_of_plane_1.png") in plot_patch.paths

    plot_patch.paths = []

    fit_imaging_plotter.figures_of_planes(subtracted_image=True,
                                          model_image=True,
                                          plane_image=True,
                                          plane_index=0)

    assert path.join(plot_path,
                     "subtracted_image_of_plane_0.png") in plot_patch.paths
    assert (path.join(plot_path, "subtracted_image_of_plane_1.png")
            not in plot_patch.paths)
    assert path.join(plot_path,
                     "model_image_of_plane_0.png") in plot_patch.paths
    assert path.join(plot_path,
                     "model_image_of_plane_1.png") not in plot_patch.paths
    assert path.join(plot_path,
                     "plane_image_of_plane_0.png") in plot_patch.paths
    assert path.join(plot_path,
                     "plane_image_of_plane_1.png") not in plot_patch.paths
def test__subplot_of_planes(masked_imaging_fit_x2_plane_7x7, include_2d_all,
                            plot_path, plot_patch):

    fit_imaging_plotter = aplt.FitImagingPlotter(
        fit=masked_imaging_fit_x2_plane_7x7,
        include_2d=include_2d_all,
        mat_plot_2d=aplt.MatPlot2D(
            output=aplt.Output(plot_path, format="png")),
    )

    fit_imaging_plotter.subplot_of_planes()

    assert path.join(plot_path, "subplot_of_plane_0.png") in plot_patch.paths
    assert path.join(plot_path, "subplot_of_plane_1.png") in plot_patch.paths

    plot_patch.paths = []

    fit_imaging_plotter.subplot_of_planes(plane_index=0)
    assert path.join(plot_path, "subplot_of_plane_0.png") in plot_patch.paths
    assert path.join(plot_path,
                     "subplot_of_plane_1.png") not in plot_patch.paths
__Fit__

Now that our source-galaxy has a `Pixelization` and `Regularization`, we are able to fit the data using these in the 
same way as before, by simply passing the source galaxy to a `Tracer` and using this `Tracer` to create a `FitImaging`
object.
"""
tracer = al.Tracer.from_galaxies(galaxies=[lens_galaxy, source_galaxy])

fit = al.FitImaging(imaging=imaging, tracer=tracer)
"""
__Inversion__

The fit has been performed using an `Inversion` for the source galaxy. We can see this by plotting the source-plane
of the `FitImaging` using the `subplot_of_plane` mat_plot_2d. Note how the bottom-right panel shows a pixelized grid.
"""
fit_imaging_plotter = aplt.FitImagingPlotter(fit=fit)
fit_imaging_plotter.subplot_of_planes(plane_index=1)
"""
__Alternative Pixelizations__

**PyAutoLens** supports many different pixel-grids. Below, we use a `VoronoiMagnification` pixelization, which defines
the source-pixel centres in the image-plane and ray traces them to the source-plane. 

The source pixel-grid is therefore adapted to the mass-model magnification pattern, placing more source-pixel in the
highly magnified regions of the source-plane.
"""
source_galaxy = al.Galaxy(
    redshift=1.0,
    pixelization=al.pix.VoronoiMagnification(shape=(40, 40)),
    regularization=al.reg.Constant(coefficient=1.0),
)
Пример #6
0
for imaging in imaging_gen:

    print(imaging)

    imaging_plotter = aplt.ImagingPlotter(imaging=imaging)
    imaging_plotter.subplot_imaging()
"""
We now use the database to load a generator containing the fit of the maximum log likelihood lens model (and therefore 
tracer) to each dataset.
"""
fit_agg = al.agg.FitImagingAgg(aggregator=agg)
fit_imaging_gen = fit_agg.max_log_likelihood_gen()

for fit in fit_imaging_gen:
    fit_imaging_plotter = aplt.FitImagingPlotter(fit=fit)
    fit_imaging_plotter.subplot_fit_imaging()
"""
__Modification__

The `FitImagingAgg` allow us to modify the fit settings. By default, it uses the `SettingsImaging`, 
`SettingsPixelization` and `SettingsInversion` that were used during the model-fit. 

However, we can change these settings such that the fit is performed differently. For example, what if I wanted  to see 
how the fit looks where the `Grid2D`'s `sub_size` is 4 (instead of the value of 2 that was used)? Or where the 
pixelization didn`t use a border? 

You can do this by passing the settings objects, which overwrite the ones used by the analysis.
"""
fit_agg = al.agg.FitImagingAgg(
    aggregator=agg,
    regularization=al.reg.Constant(coefficient=1.0),
)

tracer = al.Tracer.from_galaxies(galaxies=[lens_galaxy, source_galaxy])

# %%
"""
Then, like before, we pass the `MaskedImaging` and `Tracer` to a `FitImaging` object. Indeed, we see some 
pretty good looking residuals - we're certainly fitting the lensed source accurately!
"""

# %%
fit = al.FitImaging(masked_imaging=masked_imaging, tracer=tracer)

include_2d = aplt.Include2D(mask=True)

fit_imaging_plotter = aplt.FitImagingPlotter(fit=fit, include_2d=include_2d)
fit_imaging_plotter.subplot_fit_imaging()

# %%
"""
And, we're done, here are a few questions to get you thinking about `Inversion``.:

 1) The `Inversion` provides the maximum log likelihood solution to the observed image. Is there a problem with seeking 
 the `best-fit`? Is there a risk that we're going to fit other things in the image than just the lensed source 
 galaxy? What happens if you reduce the `regularization_coefficient` above to zero?

 2) The exterior pixels in the `Rectangular` `Grid`.have no image-pixels in them. However, they are still given a 
 reconstructed flux. If this value isn't` coming from a util to an image-pixel, where is it be coming from?
"""
        sersic_index=1.5,
    ),
    light_3=al.lp.EllSersic(
        centre=(-0.3, -0.3),
        elliptical_comps=al.convert.elliptical_comps_from(axis_ratio=0.9,
                                                          angle=85.0),
        intensity=0.4,
        effective_radius=0.1,
        sersic_index=2.0,
    ),
)

tracer = al.Tracer.from_galaxies(galaxies=[lens_galaxy, source_galaxy])

true_fit = al.FitImaging(dataset=imaging, tracer=tracer)

fit_imaging_plotter = aplt.FitImagingPlotter(fit=true_fit)
fit_imaging_plotter.subplot_fit_imaging()
fit_imaging_plotter.subplot_of_planes(plane_index=1)
"""
And indeed, we see an improved residual-map, chi-squared-map, and so forth.

If the source morphology is complex, there is no way we chain searches to fit it perfectly. The non-linear parameter 
space simply becomes too complex. For this tutorial, this was true even though our source model could actually fit 
the data perfectly. For  real lenses, the source may be *even more complex* giving us even less hope of getting a 
good fit.

But fear not, **PyAutoLens** has you covered. In chapter 4, we'll introduce a completely new way to model the source 
galaxy, which addresses the problem faced here.
"""
    search=af.DynestyStatic(path_prefix="howtolens",
                            name="phase_t2_custom_priors",
                            n_live_points=40),
    settings=settings,
    galaxies=af.CollectionPriorModel(lens=lens, source=source),
)

print(
    "Dynesty has begun running - checkout the autolens_workspace/output/2_custom_priors"
    " folder for live output of the results, images and lens model."
    " This Jupyter notebook cell with progress once Dynesty has completed - this could take some time!"
)

result = phase.run(dataset=imaging, mask=mask)

fit_imaging_plotter = aplt.FitImagingPlotter(fit=result.max_log_likelihood_fit)
fit_imaging_plotter.subplot_fit_imaging()

print("Dynesty has finished run - you may now continue the notebook.")

# %%
"""
And, we're done. This tutorial had some pretty difficult concepts to wrap your head around. However, I can`t emphasize 
enough how important it is that you develop an intuition for non-linear searches and the notion of a non-linear 
parameter space. Becoming good at lens modeling is all being able to navigate a complex, degenerate and highly 
non-linear parameter space! Luckily, we're going to keep thinking about this in the next set of tutorials, so if 
you're not feeling too confident yet, you will be soon!

Before continuing to the next tutorial, I want you think about whether anything could go wrong when we search a 
non-linear parameter space. Is it possible that we won't find the highest log likelihood lens model? Why might this be?
)

analysis = al.AnalysisImaging(dataset=imaging)

print(
    "Dynesty has begun running - checkout the workspace/output"
    "  folder for live output of the results, images and lens model."
    "  This Jupyter notebook cell with progress once Dynesty has completed - this could take some time!"
)

result_slow = search.fit(model=model, analysis=analysis)

"""
Lets check that we get a good model and fit to the data.
"""
fit_imaging_plotter = aplt.FitImagingPlotter(fit=result_slow.max_log_likelihood_fit)
fit_imaging_plotter.subplot_fit_imaging()

"""
We can use the result to tell us how many iterations Dynesty took to convergence on the solution.
"""
print("Total Dynesty Iterations (If you skip running the search, this is ~ 500000):")
print(result_slow.samples.total_samples)

"""
Now lets run the search with fast settings, so we can compare the total number of iterations required.
"""
search = af.DynestyStatic(
    path_prefix=path.join("howtolens", "chapter_2"),
    name="tutorial_searches_fast",
    unique_tag=dataset_name,
    "Dynesty has begun running - checkout the workspace/output/5_linking_phases"
    " folder for live output of the results, images and lens model."
    " This Jupyter notebook cell with progress once Dynesty has completed - this could take some time!"
)

phase1_result = phase1.run(dataset=imaging, mask=mask)

print("Dynesty has finished run - you may now continue the notebook.")

# %%
"""
And indeed, we get a reasonably good model and fit to the data - in a much shorter space of time!
"""

# %%
fit_imaging_plotter = aplt.FitImagingPlotter(
    fit=phase1_result.max_log_likelihood_fit)
fit_imaging_plotter.subplot_fit_imaging()

# %%
"""
Now all we need to do is look at the results of phase 1 and tune our priors in phase 2 to those result. Lets setup 
a custom phase that does exactly that.

GaussianPriors are a nice way to do this. They tell the `NonLinearSearch` where to look, but leave open the 
possibility that there might be a better solution nearby. In contrast, UniformPriors put hard limits on what values a 
parameter can or can`t take. It makes it more likely we'll accidently cut-out the global maxima solution.
"""

# %%
lens = al.GalaxyModel(redshift=0.5,
                      bulge=al.lp.EllipticalSersic,
Пример #12
0
    return al.FitImaging(imaging=imaging, tracer=tracer)


"""
__Fit Problems__

Lets fit our first source which was simulated using the flattest light profile. One should note that this uses the 
highest regularization coefficient of our 3 fits (as determined by maximizing the Bayesian log evidence).
"""
fit_flat = fit_imaging_with_voronoi_magnification_pixelization(
    imaging=imaging_source_flat, mask=mask, coefficient=9.2
)

include_2d = aplt.Include2D(mapper_data_pixelization_grid=True, mask=True)

fit_imaging_plotter = aplt.FitImagingPlotter(fit=fit_flat, include_2d=include_2d)
fit_imaging_plotter.subplot_fit_imaging()
fit_imaging_plotter.subplot_of_planes(plane_index=1)


print(fit_flat.log_evidence)

"""
The fit was *excellent*. There were effectively no residuals in the fit, and the source has been reconstructed using 
lots of pixels! Nice!

Now, lets fit the next source, which is more compact.
"""
fit_compact = fit_imaging_with_voronoi_magnification_pixelization(
    imaging=imaging_source_compact, mask=mask, coefficient=3.3
)

"""
__Pixelization__

Okay, so lets look at our fit from the previous tutorial in more detail. we'll use a higher resolution 40 x 40 grid.
"""
source_galaxy = al.Galaxy(
    redshift=1.0,
    pixelization=al.pix.Rectangular(shape=(40, 40)),
    regularization=al.reg.Constant(coefficient=1.0),
)

fit = perform_fit_with_source_galaxy(imaging=imaging, source_galaxy=source_galaxy)

fit_imaging_plotter = aplt.FitImagingPlotter(fit=fit)
fit_imaging_plotter.subplot_fit_imaging()

"""
__Regularization__

The source reconstruction looks excellent! 

However, the high quality of this solution was possible because I chose a `coefficient` for the regularization input of
1.0. If we reduce this `coefficient` to zero, the source reconstruction goes *very* weird.
"""
source_galaxy = al.Galaxy(
    redshift=1.0,
    pixelization=al.pix.Rectangular(shape=(40, 40)),
    regularization=al.reg.Constant(coefficient=0.0),
)
Пример #14
0
print(
    "Dynesty has begun running - checkout the workspace/output/howtolens/chapter_2/tutorial_4_custom_priors"
    " folder for live output of the results, images and lens model."
    " This Jupyter notebook cell with progress once Dynesty has completed - this could take some time!"
)

result_custom_priors = search.fit(model=model, analysis=analysis)

print("Dynesty has finished run - you may now continue the notebook.")
"""
__Result__

Bam! We get a good model, which corresponds to the global maxima. By giving our non-linear search a helping hand and 
informing it of where to sample parameter space, we can increase the odds that we find the global maxima solution.
"""
fit_imaging_plotter = aplt.FitImagingPlotter(
    fit=result_custom_priors.max_log_likelihood_fit)
fit_imaging_plotter.subplot_fit_imaging()
"""
__Discussion__

By tuning our priors to the lens we fit we increase the chance of inferring the global maxima lens model. The search
may also fit the lens model a lot faster, given it spends less time searches regions of parameter space that do not
correspond to good solutions. 

Before moving onto the next approach, lets think about the advantages and disadvantages of prior tuning:

Advantages: 

 - We have a higher chance of finding the globally maximum log likelihood solutions in parameter space.
 - The search took less time to run because the non-linear search explored less of parameter space.