# %%
inversion = al.Inversion(
    masked_dataset=masked_imaging,
    mapper=mapper,
    regularization=al.reg.Constant(coefficient=1.0),
)

# %%
"""
Our `Inversion` has a reconstructed image and `Pixeilzation`, whcih we can plot using an `InversionPlotter`
"""

# %%
include_2d = aplt.Include2D(mask=True)

inversion_plotter = aplt.InversionPlotter(inversion=inversion,
                                          include_2d=include_2d)
inversion_plotter.figures(reconstructed_image=True, reconstruction=True)

# %%
"""
And there we have it, we've successfully reconstructed, or, *inverted*, our source using the mapper`s rectangular 
grid. Whilst this source was simple (a blob of light in the centre of the source-plane), `Inversion`'s come into their 
own when fitting sources with complex morphologies. Infact, given we're having so much fun inverting things, lets 
invert a really complex source!
"""

# %%
dataset_name = "mass_sie__source_sersic_x5"
dataset_path = path.join("dataset", "howtolens", "chapter_4", dataset_name)

imaging = al.Imaging.from_fits(
reconstructed fluxes of every source-pixel pair multiplied by the `coefficient`. By setting the regularization 
coefficient to zero, we set this penalty term to zero, meaning that regularization is completely omitted.

Why do we need to regularize our solution? We just saw why, if we do not apply this smoothness prior to the source, we 
`over-fit` the image and reconstruct a noisy source with lots of extraneous features. This is what the  large flux 
values located at the exterior regions of the source reconstruction above are. If the inversions's sole aim is to 
maximize the log likelihood, it can do this by fitting *everything* accurately, including the noise.

If we change the `vmax` and `vmin` variables of the `Plotter`'s `CMap` such that the color-map is restricted to a 
narrower range of values, we can see that even without regularization we are still reconstructing the actual source 
galaxy.
"""
mat_plot_2d = aplt.MatPlot2D(cmap=aplt.Cmap(vmax=0.5, vmin=-0.5))

inversion_plotter = aplt.InversionPlotter(
    inversion=no_regularization_fit.inversion, mat_plot_2d=mat_plot_2d
)
inversion_plotter.figures_2d_of_mapper(mapper_index=0, reconstruction=True)

"""
Over-fitting is why regularization is necessary. Solutions like this will completely ruin our attempts to model a 
strong lens. By smoothing our source reconstruction we ensure it does not over fit noise in the image. 

So, what happens if we apply a high value for the regularization coefficient?
"""
source_galaxy = al.Galaxy(
    redshift=1.0,
    pixelization=al.pix.Rectangular(shape=(40, 40)),
    regularization=al.reg.Constant(coefficient=100.0),
)
"""
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)

inversion = al.Inversion(dataset=imaging,
                         mapper=mapper,
                         regularization=al.reg.Constant(coefficient=1.0))
"""
Finally, lets plot: 

 - The reconstruction of the source _Galaxy- in the source-plane.
 - The corresponding reconstructed image-plane image of the lensed source `Galaxy` (which accounts for PSF blurring).
 - The residuals of the fit to the `Imaging`.
"""
inversion_plotter = aplt.InversionPlotter(inversion=inversion)
inversion_plotter.figures_2d(reconstructed_image=True, reconstruction=True)

residual_map = imaging.image - inversion.mapped_reconstructed_image
array_plotter = aplt.Array2DPlotter(array=residual_map)
array_plotter.figure_2d()
"""
In this example, we assumed the source galaxy's true `LightProfile` or guessed a value for the `Regularization` 
coefficient. In a realistic settings we may not know this, so checkout the script `input_deflections_model.py` in 
this folder to see how we can use the `InputDeflections` to perform lens modeling whereby we infer the source 
galaxy `LightProfile` or `Inversion`.
"""
예제 #4
0
"""
We can extract the `Inversion` from the `Tracer` by passing it the imaging data.
"""
inversion = tracer.inversion_imaging_from(
    grid=imaging.grid,
    image=imaging.image,
    noise_map=imaging.noise_map,
    w_tilde=imaging.w_tilde,
    convolver=imaging.convolver,
)

"""
We can customize the filling of Voronoi cells using the `VoronoiDrawer` object which wraps the 
method `matplotlib.fill()`:

https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.fill.html
"""
voronoi_drawer = aplt.VoronoiDrawer(edgecolor="b", linewidth=1.0, linestyle="--")

mat_plot_2d = aplt.MatPlot2D(voronoi_drawer=voronoi_drawer)

"""
We now pass the inversion to a `InversionPlotter` which we will use to illustrate customization with 
the `VoronoiDrawer` object.
"""
inversion_plotter = aplt.InversionPlotter(inversion=inversion, mat_plot_2d=mat_plot_2d)

inversion_plotter.figures_2d_of_mapper(mapper_index=0, reconstruction=True)
inversion_plotter.subplot_of_mapper(mapper_index=0)