diff --git a/autolens/__init__.py b/autolens/__init__.py index 3e250e6f2..8bb53f6a4 100644 --- a/autolens/__init__.py +++ b/autolens/__init__.py @@ -16,7 +16,6 @@ from autoarray.inversion.pixelization.mesh.abstract import AbstractMesh from autoarray.inversion.regularization.abstract import AbstractRegularization from autoarray.inversion.pixelization.pixelization import Pixelization -from autoarray.inversion.pixelization.settings import SettingsPixelization from autoarray.inversion.inversion.settings import SettingsInversion from autoarray.inversion.inversion.factory import inversion_from as Inversion from autoarray.inversion.inversion.factory import ( @@ -48,6 +47,7 @@ from autoarray.structures.visibilities import VisibilitiesNoiseMap from autogalaxy import cosmology as cosmo +from autogalaxy.analysis.adapt_images import AdaptImages from autogalaxy.gui.clicker import Clicker from autogalaxy.gui.scribbler import Scribbler from autogalaxy.galaxy.galaxy import Galaxy @@ -83,7 +83,6 @@ from . import plot from . import aggregator as agg from .lens import subhalo -from .analysis.settings import SettingsLens from .lens.ray_tracing import Tracer from .lens.to_inversion import TracerToInversion from .analysis.positions import PositionsLHResample diff --git a/autolens/aggregator/fit_imaging.py b/autolens/aggregator/fit_imaging.py index 2df1d918c..301e14aff 100644 --- a/autolens/aggregator/fit_imaging.py +++ b/autolens/aggregator/fit_imaging.py @@ -19,7 +19,6 @@ def _fit_imaging_from( fit: af.Fit, galaxies: List[ag.Galaxy], settings_dataset: aa.SettingsImaging = None, - settings_pixelization: aa.SettingsPixelization = None, settings_inversion: aa.SettingsInversion = None, use_preloaded_grid: bool = True, ) -> List[FitImaging]: @@ -30,7 +29,6 @@ def _fit_imaging_from( - The imaging data, noise-map, PSF and settings as .fits files (e.g. `dataset/data.fits`). - The mask used to mask the `Imaging` data structure in the fit (`dataset/mask.fits`). - - The settings of pixelization used by the fit (`dataset/settings_pixelization.json`). - The settings of inversions used by the fit (`dataset/settings_inversion.json`). Each individual attribute can be loaded from the database via the `fit.value()` method. @@ -53,8 +51,6 @@ def _fit_imaging_from( A list of galaxies corresponding to a sample of a non-linear search and model-fit. settings_dataset Optionally overwrite the `SettingsImaging` of the `Imaging` object that is created from the fit. - settings_pixelization - Optionally overwrite the `SettingsPixelization` of the `Pixelization` object that is created from the fit. settings_inversion Optionally overwrite the `SettingsInversion` of the `Inversion` object that is created from the fit. use_preloaded_grid @@ -67,9 +63,8 @@ def _fit_imaging_from( tracer_list = _tracer_from(fit=fit, galaxies=galaxies) - settings_pixelization = settings_pixelization or fit.value( - name="settings_pixelization" - ) + adapt_images_list = agg_util.adapt_images_from(fit=fit) + settings_inversion = settings_inversion or fit.value(name="settings_inversion") mesh_grids_of_planes_list = agg_util.mesh_grids_of_planes_list_from( @@ -78,8 +73,8 @@ def _fit_imaging_from( fit_dataset_list = [] - for dataset, tracer, mesh_grids_of_planes in zip( - dataset_list, tracer_list, mesh_grids_of_planes_list + for dataset, tracer, adapt_images, mesh_grids_of_planes in zip( + dataset_list, tracer_list, adapt_images_list, mesh_grids_of_planes_list ): preloads = agg_util.preloads_from( preloads_cls=Preloads, @@ -92,7 +87,7 @@ def _fit_imaging_from( FitImaging( dataset=dataset, tracer=tracer, - settings_pixelization=settings_pixelization, + adapt_images=adapt_images, settings_inversion=settings_inversion, preloads=preloads, ) @@ -106,7 +101,6 @@ def __init__( self, aggregator: af.Aggregator, settings_dataset: Optional[aa.SettingsImaging] = None, - settings_pixelization: Optional[aa.SettingsPixelization] = None, settings_inversion: Optional[aa.SettingsInversion] = None, use_preloaded_grid: bool = True, ): @@ -118,7 +112,6 @@ def __init__( - The imaging data, noise-map, PSF and settings as .fits files (e.g. `dataset/data.fits`). - The mask used to mask the `Imaging` data structure in the fit (`dataset/mask.fits`). - - The settings of pixelization used by the fit (`dataset/settings_pixelization.json`). - The settings of inversions used by the fit (`dataset/settings_inversion.json`). The `aggregator` contains the path to each of these files, and they can be loaded individually. This class @@ -143,8 +136,6 @@ def __init__( A `PyAutoFit` aggregator object which can load the results of model-fits. settings_dataset Optionally overwrite the `SettingsImaging` of the `Imaging` object that is created from the fit. - settings_pixelization - Optionally overwrite the `SettingsPixelization` of the `Pixelization` object that is created from the fit. settings_inversion Optionally overwrite the `SettingsInversion` of the `Inversion` object that is created from the fit. use_preloaded_grid @@ -155,7 +146,6 @@ def __init__( super().__init__(aggregator=aggregator) self.settings_dataset = settings_dataset - self.settings_pixelization = settings_pixelization self.settings_inversion = settings_inversion self.use_preloaded_grid = use_preloaded_grid @@ -176,7 +166,6 @@ def object_via_gen_from(self, fit, galaxies) -> List[FitImaging]: fit=fit, galaxies=galaxies, settings_dataset=self.settings_dataset, - settings_pixelization=self.settings_pixelization, settings_inversion=self.settings_inversion, use_preloaded_grid=self.use_preloaded_grid, ) diff --git a/autolens/aggregator/fit_interferometer.py b/autolens/aggregator/fit_interferometer.py index 1b9999191..0eac6e109 100644 --- a/autolens/aggregator/fit_interferometer.py +++ b/autolens/aggregator/fit_interferometer.py @@ -19,7 +19,6 @@ def _fit_interferometer_from( galaxies: List[ag.Galaxy], real_space_mask: Optional[aa.Mask2D] = None, settings_dataset: aa.SettingsInterferometer = None, - settings_pixelization: aa.SettingsPixelization = None, settings_inversion: aa.SettingsInversion = None, use_preloaded_grid: bool = True, ) -> List[FitInterferometer]: @@ -30,7 +29,6 @@ def _fit_interferometer_from( - The interferometer data, noise-map, uv-wavelengths and settings as .fits files (e.g. `dataset/data.fits`). - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). - - The settings of pixelization used by the fit (`dataset/settings_pixelization.json`). - The settings of inversions used by the fit (`dataset/settings_inversion.json`). Each individual attribute can be loaded from the database via the `fit.value()` method. @@ -54,8 +52,6 @@ def _fit_interferometer_from( A list of galaxies corresponding to a sample of a non-linear search and model-fit. settings_dataset Optionally overwrite the `SettingsInterferometer` of the `Interferometer` object that is created from the fit. - settings_pixelization - Optionally overwrite the `SettingsPixelization` of the `Pixelization` object that is created from the fit. settings_inversion Optionally overwrite the `SettingsInversion` of the `Inversion` object that is created from the fit. use_preloaded_grid @@ -70,9 +66,8 @@ def _fit_interferometer_from( ) tracer_list = _tracer_from(fit=fit, galaxies=galaxies) - settings_pixelization = settings_pixelization or fit.value( - name="settings_pixelization" - ) + adapt_images_list = agg_util.adapt_images_from(fit=fit) + settings_inversion = settings_inversion or fit.value(name="settings_inversion") mesh_grids_of_planes_list = agg_util.mesh_grids_of_planes_list_from( @@ -81,8 +76,8 @@ def _fit_interferometer_from( fit_dataset_list = [] - for dataset, tracer, mesh_grids_of_planes in zip( - dataset_list, tracer_list, mesh_grids_of_planes_list + for dataset, tracer, adapt_images, mesh_grids_of_planes in zip( + dataset_list, tracer_list, adapt_images_list, mesh_grids_of_planes_list ): preloads = agg_util.preloads_from( preloads_cls=Preloads, @@ -95,7 +90,7 @@ def _fit_interferometer_from( FitInterferometer( dataset=dataset, tracer=tracer, - settings_pixelization=settings_pixelization, + adapt_images=adapt_images, settings_inversion=settings_inversion, preloads=preloads, ) @@ -109,7 +104,6 @@ def __init__( self, aggregator: af.Aggregator, settings_dataset: Optional[aa.SettingsInterferometer] = None, - settings_pixelization: Optional[aa.SettingsPixelization] = None, settings_inversion: Optional[aa.SettingsInversion] = None, use_preloaded_grid: bool = True, real_space_mask: Optional[aa.Mask2D] = None, @@ -122,7 +116,6 @@ def __init__( - The interferometer data, noise-map, uv-wavelengths and settings as .fits files (e.g. `dataset/data.fits`). - The real space mask defining the grid of the interferometer for the FFT (`dataset/real_space_mask.fits`). - - The settings of pixelization used by the fit (`dataset/settings_pixelization.json`). - The settings of inversions used by the fit (`dataset/settings_inversion.json`). The `aggregator` contains the path to each of these files, and they can be loaded individually. This class @@ -143,8 +136,6 @@ def __init__( A `PyAutoFit` aggregator object which can load the results of model-fits. settings_dataset Optionally overwrite the `SettingsInterferometer` of the `Interferometer` object that is created from the fit. - settings_pixelization - Optionally overwrite the `SettingsPixelization` of the `Pixelization` object that is created from the fit. settings_inversion Optionally overwrite the `SettingsInversion` of the `Inversion` object that is created from the fit. use_preloaded_grid @@ -155,7 +146,6 @@ def __init__( super().__init__(aggregator=aggregator) self.settings_dataset = settings_dataset - self.settings_pixelization = settings_pixelization self.settings_inversion = settings_inversion self.use_preloaded_grid = use_preloaded_grid self.real_space_mask = real_space_mask @@ -177,7 +167,6 @@ def object_via_gen_from(self, fit, galaxies) -> FitInterferometer: fit=fit, galaxies=galaxies, settings_dataset=self.settings_dataset, - settings_pixelization=self.settings_pixelization, settings_inversion=self.settings_inversion, use_preloaded_grid=self.use_preloaded_grid, ) diff --git a/autolens/aggregator/subhalo.py b/autolens/aggregator/subhalo.py index 1b0420dac..f13874b39 100644 --- a/autolens/aggregator/subhalo.py +++ b/autolens/aggregator/subhalo.py @@ -11,7 +11,6 @@ def __init__( self, aggregator_grid_search: af.GridSearchAggregator, settings_dataset: Optional[aa.SettingsImaging] = None, - settings_pixelization: Optional[aa.SettingsPixelization] = None, settings_inversion: Optional[aa.SettingsInversion] = None, use_preloaded_grid: bool = True, ): @@ -22,7 +21,6 @@ def __init__( self.aggregator_grid_search = aggregator_grid_search self.settings_dataset = settings_dataset - self.settings_pixelization = settings_pixelization self.settings_inversion = settings_inversion self.use_preloaded_grid = use_preloaded_grid diff --git a/autolens/aggregator/tracer.py b/autolens/aggregator/tracer.py index ea3f129a4..3f6de8e82 100644 --- a/autolens/aggregator/tracer.py +++ b/autolens/aggregator/tracer.py @@ -38,14 +38,12 @@ def _tracer_from(fit: af.Fit, galaxies: List[ag.Galaxy]) -> List[Tracer]: A list of galaxies corresponding to a sample of a non-linear search and model-fit. """ - galaxies = agg_util.galaxies_with_adapt_images_from(fit=fit, galaxies=galaxies) - if len(fit.children) > 0: logger.info( """ Using database for a fit with multiple summed Analysis objects. - Tracer objects do not fully support this yet (e.g. adapt images may not be set up correctly) + Tracer objects do not fully support this yet (e.g. model parameters which vary over analyses may be incorrect) so proceed with caution! """ ) diff --git a/autolens/analysis/analysis.py b/autolens/analysis/analysis.py index 44f878077..3a9b32777 100644 --- a/autolens/analysis/analysis.py +++ b/autolens/analysis/analysis.py @@ -23,7 +23,6 @@ from autolens.analysis.positions import PositionsLHPenalty from autolens.analysis.visualizer import Visualizer from autolens.lens.ray_tracing import Tracer -from autolens.analysis.settings import SettingsLens from autolens.lens import ray_tracing_util @@ -40,7 +39,6 @@ def __init__( positions_likelihood: Optional[ Union[PositionsLHResample, PositionsLHPenalty] ] = None, - settings_lens: SettingsLens = SettingsLens(), cosmology: ag.cosmo.LensingCosmology = ag.cosmo.Planck15(), ): """ @@ -55,14 +53,10 @@ def __init__( Parameters ---------- - settings_lens - Settings controlling the lens calculation, for example how close the lensed source's multiple images have - to trace within one another in the source plane for the model to not be discarded. cosmology The Cosmology assumed for this analysis. """ self.cosmology = cosmology - self.settings_lens = settings_lens or SettingsLens() self.positions_likelihood = positions_likelihood def tracer_via_instance_from( @@ -160,11 +154,9 @@ def __init__( positions_likelihood: Optional[ Union[PositionsLHResample, PositionsLHPenalty] ] = None, - adapt_result=None, + adapt_images: Optional[ag.AdaptImages] = None, cosmology: ag.cosmo.LensingCosmology = ag.cosmo.Planck15(), - settings_pixelization: aa.SettingsPixelization = None, settings_inversion: aa.SettingsInversion = None, - settings_lens: SettingsLens = None, raise_inversion_positions_likelihood_exception: bool = True, ): """ @@ -184,17 +176,14 @@ def __init__( An object which alters the likelihood function to include a term which accounts for whether image-pixel coordinates in arc-seconds corresponding to the multiple images of the lensed source galaxy trace close to one another in the source-plane. + adapt_images + Contains the adapt-images which are used to make a pixelization's mesh and regularization adapt to the + reconstructed galaxy's morphology. cosmology The AstroPy Cosmology assumed for this analysis. - settings_pixelization - settings controlling how a pixelization is fitted during the model-fit, for example if a border is used - when creating the pixelization. settings_inversion Settings controlling how an inversion is fitted during the model-fit, for example which linear algebra formalism is used. - settings_lens - Settings controlling the lens calculation, for example how close the lensed source's multiple images have - to trace within one another in the source plane for the model to not be discarded. raise_inversion_positions_likelihood_exception If an inversion is used without the `positions_likelihood` it is likely a systematic solution will be inferred, in which case an Exception is raised before the model-fit begins to inform the user @@ -204,21 +193,17 @@ def __init__( super().__init__( dataset=dataset, - adapt_result=adapt_result, + adapt_images=adapt_images, cosmology=cosmology, - settings_pixelization=settings_pixelization, settings_inversion=settings_inversion, ) AnalysisLensing.__init__( self=self, positions_likelihood=positions_likelihood, - settings_lens=settings_lens, cosmology=cosmology, ) - self.settings_lens = settings_lens or SettingsLens() - self.preloads = self.preloads_cls() self.raise_inversion_positions_likelihood_exception = ( @@ -297,9 +282,6 @@ def save_results(self, paths: af.DirectoryPaths, result: ResultDataset): - The maximum log likelihood tracer of the fit. - - The stochastic log likelihoods of a pixelization, provided the pixelization has functionality that can - compute likelihoods for different KMeans seeds and grids (e.g. `VoronoiBrightnessImage). - Parameters ---------- paths @@ -332,105 +314,3 @@ def save_results(self, paths: af.DirectoryPaths, result: ResultDataset): result.max_log_likelihood_fit.tracer_to_inversion.image_plane_mesh_grid_pg_list ), ) - - if conf.instance["general"]["adapt"]["stochastic_outputs"]: - if len(image_mesh_list) > 0: - for image_mesh in image_mesh_list: - if image_mesh.is_stochastic: - self.save_stochastic_outputs( - paths=paths, samples=result.samples - ) - - def log_likelihood_cap_from( - self, stochastic_log_likelihoods_json_file: str - ) -> float: - """ - Certain `Inversion`'s have stochasticity in their log likelihood estimate (e.g. due to how different KMeans - seeds change the pixelization constructed by a `VoronoiBrightnessImage` pixelization). - - A log likelihood cap can be applied to model-fits performed using these `Inversion`'s to improve error and - posterior estimates. This log likelihood cap is estimated from a list of stochastic log likelihoods, where - these log likelihoods are computed using the same model but with different KMeans seeds. - - This function computes the log likelihood cap of a model-fit by loading a set of stochastic log likelihoods - from a .json file and fitting them with a 1D Gaussian. The cap is the mean value of this Gaussian. - - Parameters - ---------- - stochastic_log_likelihoods_json_file - A .json file which loads an ndarray of stochastic log likelihoods, which are likelihoods computed using the - same model but with different KMeans seeds. - - Returns - ------- - float - A log likelihood cap which is applied in a stochastic model-fit to give improved error and posterior - estimates. - """ - try: - with open(stochastic_log_likelihoods_json_file, "r") as f: - stochastic_log_likelihoods = np.asarray(json.load(f)) - except FileNotFoundError: - raise exc.AnalysisException( - "The file 'stochastic_log_likelihoods.json' could not be found in the output of the model-fitting results" - "in the analysis before the stochastic analysis. Rerun PyAutoLens with `stochastic_outputs=True` in the" - "`general.ini` configuration file." - ) - - mean, sigma = norm.fit(stochastic_log_likelihoods) - - return mean - - def stochastic_log_likelihoods_via_instance_from(self, instance) -> List[float]: - raise NotImplementedError() - - def save_stochastic_outputs(self, paths: af.DirectoryPaths, samples: af.Samples): - """ - Certain `Inversion`'s have stochasticity in their log likelihood estimate (e.g. due to how different KMeans - seeds change the pixelization constructed by a `VoronoiBrightnessImage` pixelization). - - This function computes the stochastic log likelihoods of such a model, which are the log likelihoods computed - using the same model but with different KMeans seeds. - - It outputs these stochastic likelihoods to a format which can be loaded via PyAutoFit's database tools, and - may also be loaded if this analysis is extended with a stochastic model-fit that applies a log likelihood cap. - - This function also outputs visualization showing a histogram of the stochastic likelihood distribution. - - Parameters - ---------- - paths - The PyAutoFit paths object which manages all paths, e.g. where the non-linear search outputs are stored, - visualization and the pickled objects used by the aggregator output by this function. - samples - A PyAutoFit object which contains the samples of the non-linear search, for example the chains of an MCMC - run of samples of the nested sampler. - """ - stochastic_log_likelihoods_json_file = path.join( - paths._files_path, "stochastic_log_likelihoods.json" - ) - - try: - with open(stochastic_log_likelihoods_json_file, "r") as f: - stochastic_log_likelihoods = np.asarray(json.load(f)) - except FileNotFoundError: - instance = samples.max_log_likelihood() - stochastic_log_likelihoods = ( - self.stochastic_log_likelihoods_via_instance_from(instance=instance) - ) - - if stochastic_log_likelihoods is None: - return - - with open(stochastic_log_likelihoods_json_file, "w") as outfile: - json.dump( - [float(evidence) for evidence in stochastic_log_likelihoods], outfile - ) - - visualizer = Visualizer(visualize_path=paths.image_path) - - visualizer.visualize_stochastic_histogram( - stochastic_log_likelihoods=stochastic_log_likelihoods, - max_log_evidence=np.max(samples.log_likelihood_list), - histogram_bins=self.settings_lens.stochastic_histogram_bins, - ) diff --git a/autolens/analysis/result.py b/autolens/analysis/result.py index fb0e9093c..78a713548 100644 --- a/autolens/analysis/result.py +++ b/autolens/analysis/result.py @@ -183,13 +183,6 @@ def positions_likelihood_from( return PositionsLHPenalty(positions=positions, threshold=threshold) return PositionsLHResample(positions=positions, threshold=threshold) - @property - def path_galaxy_tuples(self) -> [(str, ag.Galaxy)]: - """ - Tuples associating the names of galaxies with instances from the best fit - """ - return self.instance.path_instance_tuples_for_class(cls=ag.Galaxy) - class ResultDataset(Result): @property @@ -197,7 +190,7 @@ def max_log_likelihood_tracer(self) -> Tracer: """ An instance of a `Tracer` corresponding to the maximum log likelihood model inferred by the non-linear search. - If a dataset is fitted the adapt images of the adapt dataset must first be associated with each galaxy. + If a dataset is fitted the adapt images of the adapt image must first be associated with each galaxy. """ instance = self.analysis.instance_with_associated_adapt_images_from( instance=self.instance @@ -243,36 +236,3 @@ def source_plane_inversion_centre(self) -> aa.Grid2DIrregular: return self.max_log_likelihood_fit.inversion.brightest_reconstruction_pixel_centre_list[ 0 ] - - def stochastic_log_likelihoods_from(self, paths: AbstractPaths) -> np.ndarray: - """ - Certain `Inversion`'s have stochasticity in their log likelihood estimate. - - For example, the `VoronoiBrightnessImage` pixelization, which changes the likelihood depending on how different - KMeans seeds change the pixel-grid. - - A log likelihood cap can be applied to model-fits performed using these `Inversion`'s to improve error and - posterior estimates. This log likelihood cap is estimated from a list of stochastic log likelihoods, where - these log likelihoods are computed using the same model but with different KMeans seeds. - - This function loads existing stochastic log likelihoods from the hard disk via a .json file. If the .json - file is not presented, then the log likelihoods are computed via the `stochastic_log_likelihoods_via_instance_from` - function of the associated Analysis class. - """ - stochastic_log_likelihoods_json_file = path.join( - paths.output_path, "stochastic_log_likelihoods.json" - ) - - paths.restore() - - try: - with open(stochastic_log_likelihoods_json_file, "r") as f: - stochastic_log_likelihoods = np.asarray(json.load(f)) - except FileNotFoundError: - self.analysis.save_stochastic_outputs(paths=paths, samples=self.samples) - with open(stochastic_log_likelihoods_json_file, "r") as f: - stochastic_log_likelihoods = np.asarray(json.load(f)) - - paths.zip_remove() - - return stochastic_log_likelihoods diff --git a/autolens/analysis/settings.py b/autolens/analysis/settings.py deleted file mode 100644 index 74620ae1a..000000000 --- a/autolens/analysis/settings.py +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Optional - - -class SettingsLens: - def __init__( - self, - stochastic_likelihood_resamples: Optional[int] = None, - stochastic_samples: int = 250, - stochastic_histogram_bins: int = 10, - ): - self.stochastic_likelihood_resamples = stochastic_likelihood_resamples - self.stochastic_samples = stochastic_samples - self.stochastic_histogram_bins = stochastic_histogram_bins diff --git a/autolens/analysis/visualizer.py b/autolens/analysis/visualizer.py index 880675506..18e72d521 100644 --- a/autolens/analysis/visualizer.py +++ b/autolens/analysis/visualizer.py @@ -1,11 +1,7 @@ -import matplotlib.pyplot as plt -import numpy as np -from scipy.stats import norm from os import path -import os -from typing import Dict import autoarray as aa +import autogalaxy as ag import autogalaxy.plot as aplt from autogalaxy.analysis.visualizer import plot_setting @@ -171,18 +167,14 @@ def should_plot(name): if should_plot("image_with_positions"): image_plotter.figure_2d() - def visualize_adapt_images( - self, - adapt_galaxy_image_path_dict: Dict[str, aa.Array2D], - adapt_model_image: aa.Array2D, - ): + def visualize_adapt_images(self, adapt_images: ag.AdaptImages): """ - Visualizes the adapt-images and adapt dataset inferred by a model-fit. + Visualizes the adapt-images and adapt image inferred by a model-fit. Images are output to the `image` folder of the `visualize_path` in a subfolder called `adapt`. When used with a non-linear search the `visualize_path` points to the search's results folder. - Visualization includes individual images of attributes of the adapt dataset (e.g. the adapt image) and + Visualization includes individual images of attributes of the adapt image (e.g. the adapt image) and a subplot of all galaxy images on the same figure. The images output by the `Visualizer` are customized using the file `config/visualize/plots.ini` under the @@ -190,10 +182,8 @@ def visualize_adapt_images( Parameters ---------- - adapt_galaxy_image_path_dict - A dictionary mapping the path to each galaxy (e.g. its name) to its corresponding galaxy image. - adapt_model_image - The adapt image which corresponds to the sum of galaxy images. + adapt_images + The adapt images (e.g. overall model image, individual galaxy images). """ def should_plot(name): @@ -206,11 +196,11 @@ def should_plot(name): ) if should_plot("model_image"): - adapt_plotter.figure_adapt_model_image(adapt_model_image=adapt_model_image) + adapt_plotter.figure_model_image(model_image=adapt_images.model_image) if should_plot("images_of_galaxies"): - adapt_plotter.subplot_adapt_images_of_galaxies( - adapt_galaxy_image_path_dict=adapt_galaxy_image_path_dict + adapt_plotter.subplot_images_of_galaxies( + adapt_galaxy_name_image_dict=adapt_images.galaxy_image_dict ) def visualize_contribution_maps(self, tracer: Tracer): @@ -222,7 +212,7 @@ def visualize_contribution_maps(self, tracer: Tracer): used with a non-linear search the `visualize_path` points to the search's results folder and this function visualizes the maximum log likelihood contribution maps inferred by the search so far. - Visualization includes individual images of attributes of the adapt dataset (e.g. the contribution map of + Visualization includes individual images of attributes of the adapt image (e.g. the contribution map of each galaxy) and a subplot of all contribution maps on the same figure. The images output by the `Visualizer` are customized using the file `config/visualize/plots.ini` under the @@ -248,70 +238,3 @@ def should_plot(name): adapt_plotter.subplot_contribution_map_list( contribution_map_list_list=tracer.contribution_map_list ) - - def visualize_stochastic_histogram( - self, - stochastic_log_likelihoods: np.ndarray, - max_log_evidence: float, - histogram_bins: int = 10, - ): - """ - Certain `Inversion`'s have stochasticity in their log likelihood estimate. - - For example, the `VoronoiBrightnessImage` pixelization, which changes the likelihood depending on how different - KMeans seeds change the pixel-grid. - - A log likelihood cap can be applied to model-fits performed using these `Inversion`'s to improve error and - posterior estimates. This log likelihood cap is estimated from a list of stochastic log likelihoods, where - these log likelihoods are computed using the same model but with different KMeans seeds. - - This function plots a histogram representing the distribution of these stochastic log likelihoods with a 1D - Gaussian fit to the likelihoods overlaid. This figure can be used to determine how subject the fit to this - dataset is to the stochastic likelihood effect. - - Parameters - ---------- - stochastic_log_likelihoods - The stochastic log likelihood which are used to plot the histogram and Gaussian. - max_log_evidence - The maximum log likelihood value of the non-linear search, which will likely be much larger than any of the - stochastic log likelihoods as it will be boosted high relative to most samples. - histogram_bins - The number of bins in the histogram used to visualize the distribution of stochastic log likelihoods. - - Returns - ------- - float - A log likelihood cap which is applied in a stochastic model-fit to give improved error and posterior - estimates. - """ - if stochastic_log_likelihoods is None: - return - - if plot_setting("other", "stochastic_histogram"): - file_path = path.join(self.visualize_path, "other") - - try: - os.makedirs(file_path) - except FileExistsError or IsADirectoryError: - pass - - filename = path.join(file_path, "stochastic_histogram.png") - - if path.exists(filename): - try: - os.rmdir(filename) - except Exception: - pass - - (mu, sigma) = norm.fit(stochastic_log_likelihoods) - n, bins, patches = plt.hist( - x=stochastic_log_likelihoods, bins=histogram_bins, density=1 - ) - y = norm.pdf(bins, mu, sigma) - plt.plot(bins, y, "--") - plt.xlabel("log evidence") - plt.title("Stochastic Log Evidence Histogram") - plt.axvline(max_log_evidence, color="r") - plt.savefig(filename, bbox_inches="tight") - plt.close() diff --git a/autolens/config/visualize/plots.yaml b/autolens/config/visualize/plots.yaml index deda74da8..cb942970d 100644 --- a/autolens/config/visualize/plots.yaml +++ b/autolens/config/visualize/plots.yaml @@ -73,8 +73,6 @@ dirty_residual_map: false dirty_normalized_residual_map: false dirty_chi_squared_map: false - other: # Settings for other plotting quantities. - stochastic_histogram: false fit_quantity: # Settings for plots of fit quantities (e.g. FitQuantityPlotter). all_at_end_png: true # Plot all individual plots listed below as .png (even if False)? all_at_end_fits: true # Plot all individual plots listed below as .fits (even if False)? diff --git a/autolens/fixtures.py b/autolens/fixtures.py index 4b0d252eb..f13046a4a 100644 --- a/autolens/fixtures.py +++ b/autolens/fixtures.py @@ -128,15 +128,43 @@ def make_fit_point_dict_x2_plane(): ) +def make_adapt_galaxy_name_image_dict_7x7(): + image_0 = ag.Array2D( + np.full(fill_value=2.0, shape=make_mask_2d_7x7().pixels_in_mask), + mask=make_mask_2d_7x7(), + ) + + image_1 = ag.Array2D( + np.full(fill_value=3.0, shape=make_mask_2d_7x7().pixels_in_mask), + mask=make_mask_2d_7x7(), + ) + + adapt_galaxy_name_image_dict = { + "('galaxies', 'lens')": image_0, + "('galaxies', 'source')": image_1, + } + + return adapt_galaxy_name_image_dict + + +def make_adapt_images_7x7(): + return ag.AdaptImages( + galaxy_name_image_dict=make_adapt_galaxy_name_image_dict_7x7(), + ) + + def make_analysis_imaging_7x7(): return al.AnalysisImaging( dataset=make_masked_imaging_7x7(), settings_inversion=aa.SettingsInversion(use_w_tilde=False), + adapt_images=make_adapt_images_7x7(), ) def make_analysis_interferometer_7(): - return al.AnalysisInterferometer(dataset=make_interferometer_7()) + return al.AnalysisInterferometer( + dataset=make_interferometer_7(), adapt_images=make_adapt_images_7x7() + ) def make_analysis_point_x2(): diff --git a/autolens/imaging/fit_imaging.py b/autolens/imaging/fit_imaging.py index e784cfc29..cff3f1e02 100644 --- a/autolens/imaging/fit_imaging.py +++ b/autolens/imaging/fit_imaging.py @@ -20,7 +20,7 @@ def __init__( self, dataset: aa.Imaging, tracer: Tracer, - settings_pixelization: aa.SettingsPixelization = aa.SettingsPixelization(), + adapt_images: Optional[ag.AdaptImages] = None, settings_inversion: aa.SettingsInversion = aa.SettingsInversion(), preloads: Preloads = Preloads(), run_time_dict: Optional[Dict] = None, @@ -55,9 +55,9 @@ def __init__( The imaging dataset which is fitted by the galaxies in the tracer. tracer The tracer of galaxies whose light profile images are used to fit the imaging data. - settings_pixelization - Settings controlling how a pixelization is fitted for example if a border is used when creating the - pixelization. + adapt_images + Contains the adapt-images which are used to make a pixelization's mesh and regularization adapt to the + reconstructed galaxy's morphology. settings_inversion Settings controlling how an inversion is fitted for example which linear algebra formalism is used. preloads @@ -75,7 +75,7 @@ def __init__( self.tracer = tracer - self.settings_pixelization = settings_pixelization + self.adapt_images = adapt_images self.settings_inversion = settings_inversion self.preloads = preloads @@ -114,7 +114,7 @@ def tracer_to_inversion(self) -> TracerToInversion: data=self.profile_subtracted_image, noise_map=self.noise_map, w_tilde=self.w_tilde, - settings_pixelization=self.settings_pixelization, + adapt_images=self.adapt_images, settings_inversion=self.settings_inversion, preloads=self.preloads, ) @@ -319,7 +319,7 @@ def refit_with_new_preloads( return FitImaging( dataset=self.dataset, tracer=self.tracer, - settings_pixelization=self.settings_pixelization, + adapt_images=self.adapt_images, settings_inversion=settings_inversion, preloads=preloads, run_time_dict=run_time_dict, diff --git a/autolens/imaging/model/analysis.py b/autolens/imaging/model/analysis.py index bc58d3894..b5afe2c6a 100644 --- a/autolens/imaging/model/analysis.py +++ b/autolens/imaging/model/analysis.py @@ -65,7 +65,7 @@ def log_likelihood_function(self, instance: af.ModelInstance) -> float: For this analysis class, this function performs the following steps: - 1) If the analysis has a adapt dataset, associated the model galaxy images of this dataset to the galaxies in + 1) If the analysis has a adapt image, associated the model galaxy images of this dataset to the galaxies in the model instance. 2) Extract attributes which model aspects of the data reductions, like the scaling the background sky @@ -108,7 +108,7 @@ def log_likelihood_function(self, instance: af.ModelInstance) -> float: return log_likelihood_positions_overwrite try: - return self.fit_imaging_via_instance_from(instance=instance).figure_of_merit + return self.fit_from(instance=instance).figure_of_merit except ( PixelizationException, exc.PixelizationException, @@ -122,7 +122,7 @@ def log_likelihood_function(self, instance: af.ModelInstance) -> float: ) as e: raise exc.FitException from e - def fit_imaging_via_instance_from( + def fit_from( self, instance: af.ModelInstance, preload_overwrite: Optional[Preloads] = None, @@ -152,123 +152,24 @@ def fit_imaging_via_instance_from( FitImaging The fit of the plane to the imaging dataset, which includes the log likelihood. """ - self.instance_with_associated_adapt_images_from(instance=instance) + tracer = self.tracer_via_instance_from( instance=instance, run_time_dict=run_time_dict ) - return self.fit_imaging_via_tracer_from( - tracer=tracer, - preload_overwrite=preload_overwrite, - run_time_dict=run_time_dict, - ) - - def fit_imaging_via_tracer_from( - self, - tracer: Tracer, - preload_overwrite: Optional[Preloads] = None, - run_time_dict: Optional[Dict] = None, - ) -> FitImaging: - """ - Given a `Tracer`, which the analysis constructs from a model instance, create a `FitImaging` object. - - This function is used in the `log_likelihood_function` to fit the model to the imaging data and compute the - log likelihood. + adapt_images = self.adapt_images_via_instance_from(instance=instance) - Parameters - ---------- - tracer - The tracer of galaxies whose ray-traced model images are used to fit the imaging data. - preload_overwrite - If a `Preload` object is input this is used instead of the preloads stored as an attribute in the analysis. - run_time_dict - A dictionary which times functions called to fit the model to data, for profiling. - - Returns - ------- - FitImaging - The fit of the plane to the imaging dataset, which includes the log likelihood. - """ preloads = preload_overwrite or self.preloads return FitImaging( dataset=self.dataset, tracer=tracer, - settings_pixelization=self.settings_pixelization, + adapt_images=adapt_images, settings_inversion=self.settings_inversion, preloads=preloads, run_time_dict=run_time_dict, ) - @property - def fit_func(self): - return self.fit_imaging_via_instance_from - - def stochastic_log_likelihoods_via_instance_from(self, instance: af.ModelInstance): - """ - Certain `Inversion`'s have stochasticity in their log likelihood estimate. - - For example, the `VoronoiBrightnessImage` pixelization, which changes the likelihood depending on how different - KMeans seeds change the pixel-grid. - - A log likelihood cap can be applied to model-fits performed using these `Inversion`'s to improve error and - posterior estimates. This log likelihood cap is estimated from a list of stochastic log likelihoods, where - these log likelihoods are computed using the same model but with different KMeans seeds. - - This function computes these stochastic log likelihoods by iterating over many model-fits using different - KMeans seeds. - - Parameters - ---------- - instance - The maximum log likelihood instance of a model that is has finished being fitted to the dataset. - - Returns - ------- - float - A log likelihood cap which is applied in a stochastic model-fit to give improved error and posterior - estimates. - """ - instance = self.instance_with_associated_adapt_images_from(instance=instance) - tracer = self.tracer_via_instance_from(instance=instance) - - if not tracer.has(cls=ag.Pixelization): - return - - if not any( - pix.image_mesh.is_stochastic for pix in tracer.cls_list_from(cls=ag.Pixelization) - ): - return - - log_evidences = [] - - for i in range(self.settings_lens.stochastic_samples): - - try: - - tracer.galaxies[-1].pixelization.image_mesh.seed = i - - log_evidence = FitImaging( - dataset=self.dataset, - tracer=tracer, - settings_pixelization=self.settings_pixelization, - settings_inversion=self.settings_inversion, - preloads=self.preloads, - ).log_evidence - except ( - PixelizationException, - exc.PixelizationException, - exc.InversionException, - exc.GridException, - OverflowError, - ) as e: - log_evidence = None - - if log_evidence is not None: - log_evidences.append(log_evidence) - - return log_evidences - def visualize_before_fit(self, paths: af.DirectoryPaths, model: af.Collection): """ PyAutoFit calls this function immediately before the non-linear search begins. @@ -295,10 +196,10 @@ def visualize_before_fit(self, paths: af.DirectoryPaths, model: af.Collection): positions=self.positions_likelihood.positions, ) - visualizer.visualize_adapt_images( - adapt_galaxy_image_path_dict=self.adapt_galaxy_image_path_dict, - adapt_model_image=self.adapt_model_image, - ) + if self.adapt_images is not None: + visualizer.visualize_adapt_images( + adapt_images=self.adapt_images + ) def visualize( self, @@ -336,9 +237,7 @@ def visualize( which may change which images are output. """ - instance = self.instance_with_associated_adapt_images_from(instance=instance) - - fit = self.fit_imaging_via_instance_from(instance=instance) + fit = self.fit_from(instance=instance) if self.positions_likelihood is not None: self.positions_likelihood.output_positions_info( @@ -418,7 +317,7 @@ def save_attributes(self, paths: af.DirectoryPaths): - The settings associated with the inversion. - The settings associated with the pixelization. - The Cosmology. - - The adapt dataset's model image and galaxy images, if used. + - The adapt image's model image and galaxy images, if used. This function also outputs attributes specific to an imaging dataset: diff --git a/autolens/imaging/model/result.py b/autolens/imaging/model/result.py index c2f2e0048..07c7acb1d 100644 --- a/autolens/imaging/model/result.py +++ b/autolens/imaging/model/result.py @@ -47,7 +47,7 @@ def max_log_likelihood_fit(self) -> FitImaging: An instance of a `FitImaging` corresponding to the maximum log likelihood model inferred by the non-linear search. """ - return self.analysis.fit_imaging_via_instance_from( + return self.analysis.fit_from( instance=self.instance, ) @@ -59,7 +59,6 @@ def max_log_likelihood_tracer(self) -> Tracer: The `Tracer` is computed from the `max_log_likelihood_fit`, as this ensures that all linear light profiles are converted to normal light profiles with their `intensity` values updated. """ - return ( self.max_log_likelihood_fit.model_obj_linear_light_profiles_to_light_profiles ) diff --git a/autolens/interferometer/fit_interferometer.py b/autolens/interferometer/fit_interferometer.py index fc53c87ae..21653f4f5 100644 --- a/autolens/interferometer/fit_interferometer.py +++ b/autolens/interferometer/fit_interferometer.py @@ -18,7 +18,7 @@ def __init__( self, dataset: aa.Interferometer, tracer: Tracer, - settings_pixelization: aa.SettingsPixelization = aa.SettingsPixelization(), + adapt_images: Optional[ag.AdaptImages] = None, settings_inversion: aa.SettingsInversion = aa.SettingsInversion(), preloads: Preloads = Preloads(), run_time_dict: Optional[Dict] = None, @@ -54,9 +54,9 @@ def __init__( The interforometer dataset which is fitted by the galaxies in the tracer. tracer The tracer of galaxies whose light profile images are used to fit the interferometer data. - settings_pixelization - Settings controlling how a pixelization is fitted for example if a border is used when creating the - pixelization. + adapt_images + Contains the adapt-images which are used to make a pixelization's mesh and regularization adapt to the + reconstructed galaxy's morphology. settings_inversion Settings controlling how an inversion is fitted for example which linear algebra formalism is used. preloads @@ -74,7 +74,8 @@ def __init__( self.tracer = tracer - self.settings_pixelization = settings_pixelization + self.adapt_images = adapt_images + self.settings_inversion = settings_inversion self.preloads = preloads @@ -112,7 +113,7 @@ def tracer_to_inversion(self) -> TracerToInversion: data=self.profile_subtracted_visibilities, noise_map=self.noise_map, w_tilde=self.w_tilde, - settings_pixelization=self.settings_pixelization, + adapt_images=self.adapt_images, settings_inversion=self.settings_inversion, preloads=self.preloads, ) @@ -268,7 +269,7 @@ def refit_with_new_preloads( return FitInterferometer( dataset=self.interferometer, tracer=self.tracer, - settings_pixelization=self.settings_pixelization, + adapt_images=self.adapt_images, settings_inversion=settings_inversion, preloads=preloads, run_time_dict=run_time_dict, diff --git a/autolens/interferometer/model/analysis.py b/autolens/interferometer/model/analysis.py index 2b8650bcd..f86c46fe5 100644 --- a/autolens/interferometer/model/analysis.py +++ b/autolens/interferometer/model/analysis.py @@ -18,7 +18,6 @@ from autolens.interferometer.model.result import ResultInterferometer from autolens.interferometer.model.visualizer import VisualizerInterferometer from autolens.interferometer.fit_interferometer import FitInterferometer -from autolens.analysis.settings import SettingsLens from autolens import exc @@ -34,11 +33,9 @@ def __init__( positions_likelihood: Optional[ Union[PositionsLHResample, PositionsLHPenalty] ] = None, - adapt_result=None, + adapt_images: Optional[ag.AdaptImages] = None, cosmology: ag.cosmo.LensingCosmology = ag.cosmo.Planck15(), - settings_pixelization: aa.SettingsPixelization = None, settings_inversion: aa.SettingsInversion = None, - settings_lens: SettingsLens = None, raise_inversion_positions_likelihood_exception: bool = True, ): """ @@ -54,7 +51,7 @@ def __init__( `Tracer`) to an interferometer dataset. This class stores the settings used to perform the model-fit for certain components of the model (e.g. a - pixelization or inversion), the Cosmology used for the analysis and adapt datasets used for certain model + pixelization or inversion), the Cosmology used for the analysis and adapt images used for certain model classes. Parameters @@ -65,19 +62,13 @@ def __init__( An object which alters the likelihood function to include a term which accounts for whether image-pixel coordinates in arc-seconds corresponding to the multiple images of the lensed source galaxy trace close to one another in the source-plane. - adapt_result - Theadapt-model image and galaxies images of a previous result in a model-fitting pipeline, which are - used by certain classes for adapting the analysis to the properties of the dataset. + adapt_images + Contains the adapt-images which are used to make a pixelization's mesh and regularization adapt to the + reconstructed galaxy's morphology. cosmology The Cosmology assumed for this analysis. - settings_pixelization - settings controlling how a pixelization is fitted for example if a border is used when creating the - pixelization. settings_inversion Settings controlling how an inversion is fitted, for example which linear algebra formalism is used. - settings_lens - Settings controlling the lens calculation, for example how close the lensed source's multiple images have - to trace within one another in the source plane for the model to not be discarded. raise_inversion_positions_likelihood_exception If an inversion is used without the `positions_likelihood` it is likely a systematic solution will be inferred, in which case an Exception is raised before the model-fit begins to inform the user @@ -87,11 +78,9 @@ def __init__( super().__init__( dataset=dataset, positions_likelihood=positions_likelihood, - adapt_result=adapt_result, + adapt_images=adapt_images, cosmology=cosmology, - settings_pixelization=settings_pixelization, settings_inversion=settings_inversion, - settings_lens=settings_lens, raise_inversion_positions_likelihood_exception=raise_inversion_positions_likelihood_exception, ) @@ -137,7 +126,7 @@ def log_likelihood_function(self, instance): For this analysis class, this function performs the following steps: - 1) If the analysis has a adapt dataset, associated the model galaxy images of this dataset to the galaxies in + 1) If the analysis has a adapt image, associated the model galaxy images of this dataset to the galaxies in the model instance. 2) Extract attributes which model aspects of the data reductions, like the scaling the background sky @@ -177,9 +166,7 @@ def log_likelihood_function(self, instance): raise e try: - return self.fit_interferometer_via_instance_from( - instance=instance - ).figure_of_merit + return self.fit_from(instance=instance).figure_of_merit except ( PixelizationException, exc.PixelizationException, @@ -193,9 +180,10 @@ def log_likelihood_function(self, instance): ) as e: raise exc.FitException from e - def fit_interferometer_via_instance_from( + def fit_from( self, instance: af.ModelInstance, + preload_overwrite: Optional[Preloads] = None, run_time_dict: Optional[Dict] = None, ) -> FitInterferometer: """ @@ -222,122 +210,24 @@ def fit_interferometer_via_instance_from( FitInterferometer The fit of the plane to the interferometer dataset, which includes the log likelihood. """ - self.instance_with_associated_adapt_images_from(instance=instance) + tracer = self.tracer_via_instance_from( instance=instance, run_time_dict=run_time_dict ) - return self.fit_interferometer_via_tracer_from( - tracer=tracer, run_time_dict=run_time_dict - ) + adapt_images = self.adapt_images_via_instance_from(instance=instance) - def fit_interferometer_via_tracer_from( - self, - tracer: Tracer, - preload_overwrite: Optional[Preloads] = None, - run_time_dict: Optional[Dict] = None, - ): - """ - Given a `Tracer`, which the analysis constructs from a model instance, create a `FitInterferometer` object. - - This function is used in the `log_likelihood_function` to fit the model to the imaging data and compute the - log likelihood. - - Parameters - ---------- - tracer - The tracer of galaxies whose ray-traced model images are used to fit the imaging data. - preload_overwrite - If a `Preload` object is input this is used instead of the preloads stored as an attribute in the analysis. - run_time_dict - A dictionary which times functions called to fit the model to data, for profiling. - - Returns - ------- - FitImaging - The fit of the plane to the imaging dataset, which includes the log likelihood. - """ preloads = self.preloads if preload_overwrite is None else preload_overwrite return FitInterferometer( dataset=self.dataset, tracer=tracer, - settings_pixelization=self.settings_pixelization, + adapt_images=adapt_images, settings_inversion=self.settings_inversion, preloads=preloads, run_time_dict=run_time_dict, ) - @property - def fit_func(self): - return self.fit_interferometer_via_instance_from - - def stochastic_log_likelihoods_via_instance_from(self, instance): - """ - Certain `Inversion`'s have stochasticity in their log likelihood estimate. - - For example, the `VoronoiBrightnessImage` pixelization, which changes the likelihood depending on how different - KMeans seeds change the pixel-grid. - - A log likelihood cap can be applied to model-fits performed using these `Inversion`'s to improve error and - posterior estimates. This log likelihood cap is estimated from a list of stochastic log likelihoods, where - these log likelihoods are computed using the same model but with different KMeans seeds. - - This function computes these stochastic log likelihoods by iterating over many model-fits using different - KMeans seeds. - - Parameters - ---------- - instance - The maximum log likelihood instance of a model that is has finished being fitted to the dataset. - - Returns - ------- - float - A log likelihood cap which is applied in a stochastic model-fit to give improved error and posterior - estimates. - """ - instance = self.instance_with_associated_adapt_images_from(instance=instance) - tracer = self.tracer_via_instance_from(instance=instance) - - if not tracer.has(cls=aa.Pixelization): - return None - - if not any( - [ - pix.image_mesh.is_stochastic - for pix in tracer.cls_list_from(cls=ag.Pixelization) - ] - ): - return - - log_evidences = [] - - for i in range(self.settings_lens.stochastic_samples): - try: - tracer.galaxies[-1].pixelization.image_mesh.seed = i - - log_evidence = FitInterferometer( - dataset=self.dataset, - tracer=tracer, - settings_pixelization=self.settings_pixelization, - settings_inversion=self.settings_inversion, - preloads=self.preloads, - ).log_evidence - except ( - PixelizationException, - exc.PixelizationException, - exc.InversionException, - exc.GridException, - OverflowError, - ) as e: - log_evidence = None - - if log_evidence is not None: - log_evidences.append(log_evidence) - - return log_evidences - def visualize_before_fit(self, paths: af.DirectoryPaths, model: af.Collection): """ PyAutoFit calls this function immediately before the non-linear search begins. @@ -364,10 +254,8 @@ def visualize_before_fit(self, paths: af.DirectoryPaths, model: af.Collection): positions=self.positions_likelihood.positions, ) - visualizer.visualize_adapt_images( - adapt_galaxy_image_path_dict=self.adapt_galaxy_image_path_dict, - adapt_model_image=self.adapt_model_image, - ) + if self.adapt_images is not None: + visualizer.visualize_adapt_images(adapt_images=self.adapt_images) def visualize(self, paths: af.DirectoryPaths, instance, during_analysis): """ @@ -402,10 +290,7 @@ def visualize(self, paths: af.DirectoryPaths, instance, during_analysis): If True the visualization is being performed midway through the non-linear search before it is finished, which may change which images are output. """ - - instance = self.instance_with_associated_adapt_images_from(instance=instance) - - fit = self.fit_interferometer_via_instance_from(instance=instance) + fit = self.fit_from(instance=instance) if self.positions_likelihood is not None: self.positions_likelihood.output_positions_info( @@ -489,7 +374,7 @@ def save_attributes(self, paths: af.DirectoryPaths): - The settings associated with the inversion. - The settings associated with the pixelization. - The Cosmology. - - The adapt dataset's model image and galaxy images, if used. + - The adapt image's model image and galaxy images, if used. This function also outputs attributes specific to an imaging dataset: diff --git a/autolens/interferometer/model/result.py b/autolens/interferometer/model/result.py index 45ebaa572..3edb5dd3a 100644 --- a/autolens/interferometer/model/result.py +++ b/autolens/interferometer/model/result.py @@ -47,9 +47,7 @@ def max_log_likelihood_fit(self) -> FitInterferometer: An instance of a `FitInterferometer` corresponding to the maximum log likelihood model inferred by the non-linear search. """ - return self.analysis.fit_interferometer_via_instance_from( - instance=self.instance - ) + return self.analysis.fit_from(instance=self.instance) @property def max_log_likelihood_tracer(self) -> Tracer: diff --git a/autolens/lens/to_inversion.py b/autolens/lens/to_inversion.py index cfc103d31..8d4716a52 100644 --- a/autolens/lens/to_inversion.py +++ b/autolens/lens/to_inversion.py @@ -18,7 +18,7 @@ def __init__( data: Optional[Union[aa.Array2D, aa.Visibilities]] = None, noise_map: Optional[Union[aa.Array2D, aa.VisibilitiesNoiseMap]] = None, w_tilde: Optional[Union[aa.WTildeImaging, aa.WTildeInterferometer]] = None, - settings_pixelization=aa.SettingsPixelization(), + adapt_images: Optional[ag.AdaptImages] = None, settings_inversion: aa.SettingsInversion = aa.SettingsInversion(), preloads=Preloads(), run_time_dict: Optional[Dict] = None, @@ -30,7 +30,7 @@ def __init__( data=data, noise_map=noise_map, w_tilde=w_tilde, - settings_pixelization=settings_pixelization, + adapt_images=adapt_images, settings_inversion=settings_inversion, preloads=preloads, run_time_dict=run_time_dict, @@ -74,6 +74,8 @@ def lp_linear_func_list_galaxy_dict( grid=traced_grids_of_planes_list[plane_index], blurring_grid=traced_blurring_grids_of_planes_list[plane_index], noise_map=self.noise_map, + settings_inversion=self.settings_inversion, + adapt_images=self.adapt_images, ) lp_linear_galaxy_dict_of_plane = ( @@ -92,9 +94,30 @@ def cls_pg_list_from(self, cls: Type) -> List: @cached_property def adapt_galaxy_image_pg_list(self) -> List: - return [ - plane.adapt_galaxies_with_pixelization_image_list for plane in self.planes - ] + adapt_galaxy_image_pg_list = [] + + for plane in self.planes: + if plane.has(cls=aa.Pixelization): + plane_image_list = [] + + galaxies_with_pixelization_list = plane.galaxies_with_cls_list_from( + cls=aa.Pixelization + ) + + for galaxy in galaxies_with_pixelization_list: + try: + image = self.adapt_images.galaxy_image_dict[galaxy] + except (AttributeError, KeyError): + image = None + + plane_image_list.append(image) + + adapt_galaxy_image_pg_list.append(plane_image_list) + + else: + adapt_galaxy_image_pg_list.append([]) + + return adapt_galaxy_image_pg_list @cached_property @aa.profile_func @@ -111,8 +134,9 @@ def image_plane_mesh_grid_pg_list(self) -> List[List]: plane_to_inversion = ag.PlaneToInversion( plane=plane, grid_pixelization=self.dataset.grid, - settings_pixelization=self.settings_pixelization, noise_map=self.noise_map, + adapt_images=self.adapt_images, + settings_inversion=self.settings_inversion, ) image_plane_mesh_grid_list = plane_to_inversion.image_plane_mesh_grid_list @@ -183,9 +207,10 @@ def mapper_galaxy_dict(self) -> Dict[aa.AbstractMapper, ag.Galaxy]: plane_to_inversion = ag.PlaneToInversion( plane=plane, grid_pixelization=traced_grids_of_planes_list[plane_index], - settings_pixelization=self.settings_pixelization, preloads=self.preloads, noise_map=self.noise_map, + adapt_images=self.adapt_images, + settings_inversion=self.settings_inversion, ) galaxies_with_pixelization_list = plane.galaxies_with_cls_list_from( @@ -197,6 +222,13 @@ def mapper_galaxy_dict(self) -> Dict[aa.AbstractMapper, ag.Galaxy]: ): pixelization_list = self.cls_pg_list_from(cls=aa.Pixelization) + try: + adapt_galaxy_image = self.adapt_galaxy_image_pg_list[ + plane_index + ][mapper_index] + except AttributeError: + adapt_galaxy_image = None + mapper = plane_to_inversion.mapper_from( mesh=pixelization_list[plane_index][mapper_index].mesh, regularization=pixelization_list[plane_index][ @@ -208,9 +240,7 @@ def mapper_galaxy_dict(self) -> Dict[aa.AbstractMapper, ag.Galaxy]: image_plane_mesh_grid=image_plane_mesh_grid_list[plane_index][ mapper_index ], - adapt_galaxy_image=self.adapt_galaxy_image_pg_list[plane_index][ - mapper_index - ], + adapt_galaxy_image=adapt_galaxy_image, ) galaxy = galaxies_with_pixelization_list[mapper_index] diff --git a/autolens/point/model/analysis.py b/autolens/point/model/analysis.py index 9aac44ede..49d89362d 100644 --- a/autolens/point/model/analysis.py +++ b/autolens/point/model/analysis.py @@ -12,7 +12,6 @@ from autolens.point.model.result import ResultPoint from autolens.point.point_solver import PointSolver -from autolens.analysis.settings import SettingsLens from autolens import exc @@ -31,7 +30,6 @@ def __init__( solver: PointSolver, dataset=None, cosmology: ag.cosmo.LensingCosmology = ag.cosmo.Planck15(), - settings_lens=SettingsLens(), ): """ The analysis performed for model-fitting a point-source dataset, for example fitting the point-sources of a @@ -52,25 +50,17 @@ def __init__( visualization. cosmology The cosmology of the ray-tracing calculation. - settings_lens - Settings which control how the model-fit is performed. """ super().__init__(cosmology=cosmology) - AnalysisLensing.__init__( - self=self, settings_lens=settings_lens, cosmology=cosmology - ) + AnalysisLensing.__init__(self=self, cosmology=cosmology) self.point_dict = point_dict self.solver = solver self.dataset = dataset - @property - def fit_func(self) -> Callable: - return self.fit_positions_for - def log_likelihood_function(self, instance): """ Determine the fit of the strong lens system of lens galaxies and source galaxies to the point source data. @@ -86,14 +76,12 @@ def log_likelihood_function(self, instance): A fractional value indicating how well this model fit and the model masked_dataset itself """ try: - fit = self.fit_positions_for(instance=instance) + fit = self.fit_from(instance=instance) return fit.log_likelihood except (AttributeError, ValueError, TypeError, NumbaException) as e: raise exc.FitException from e - def fit_positions_for( - self, instance, run_time_dict: Optional[Dict] = None - ) -> FitPointDict: + def fit_from(self, instance, run_time_dict: Optional[Dict] = None) -> FitPointDict: tracer = self.tracer_via_instance_from( instance=instance, run_time_dict=run_time_dict ) diff --git a/autolens/point/model/result.py b/autolens/point/model/result.py index 0c0ffc55f..642cc2487 100644 --- a/autolens/point/model/result.py +++ b/autolens/point/model/result.py @@ -10,4 +10,4 @@ def grid(self): @property def max_log_likelihood_fit(self): - return self.analysis.fit_positions_for(instance=self.instance) + return self.analysis.fit_from(instance=self.instance) diff --git a/autolens/quantity/model/analysis.py b/autolens/quantity/model/analysis.py index f09a2b03d..276f1013e 100644 --- a/autolens/quantity/model/analysis.py +++ b/autolens/quantity/model/analysis.py @@ -7,7 +7,6 @@ from autolens.analysis.visualizer import Visualizer from autolens.analysis.analysis import AnalysisLensing -from autolens.analysis.settings import SettingsLens from autogalaxy.quantity.plot.fit_quantity_plotters import FitQuantityPlotter from autolens.quantity.model.result import ResultQuantity from autolens.quantity.fit_quantity import FitQuantity @@ -19,7 +18,6 @@ def __init__( dataset: ag.DatasetQuantity, func_str: str, cosmology: ag.cosmo.LensingCosmology = ag.cosmo.Planck15(), - settings_lens=SettingsLens(), ): """ Analysis classes are used by PyAutoFit to fit a model to a dataset via a non-linear search. @@ -50,15 +48,10 @@ def __init__( the dataset. cosmology The Cosmology assumed for this analysis. - settings_lens - Settings controlling the lens calculation, for example how close the lensed source's multiple images have - to trace within one another in the source plane for the model to not be discarded. """ super().__init__(dataset=dataset, func_str=func_str, cosmology=cosmology) - AnalysisLensing.__init__( - self=self, settings_lens=settings_lens, cosmology=cosmology - ) + AnalysisLensing.__init__(self=self, cosmology=cosmology) def fit_quantity_for_instance(self, instance: af.ModelInstance) -> FitQuantity: """ diff --git a/autolens/quantity/model/result.py b/autolens/quantity/model/result.py index d320f11b9..ab72e5469 100644 --- a/autolens/quantity/model/result.py +++ b/autolens/quantity/model/result.py @@ -50,7 +50,7 @@ def max_log_likelihood_tracer(self) -> Tracer: """ An instance of a `Tracer` corresponding to the maximum log likelihood model inferred by the non-linear search. - If a dataset is fitted the adapt images of the adapt dataset must first be associated with each galaxy. + If a dataset is fitted the adapt images of the adapt image must first be associated with each galaxy. """ return self.analysis.tracer_via_instance_from(instance=self.instance) diff --git a/docs/api/galaxy.rst b/docs/api/galaxy.rst index 20d097f10..5897d8c46 100644 --- a/docs/api/galaxy.rst +++ b/docs/api/galaxy.rst @@ -15,7 +15,6 @@ Galaxy / Plane / Tracer Galaxy Plane Tracer - SettingsLens To treat the redshift of a galaxy as a free parameter in a model, the ``Redshift`` object must be used. diff --git a/docs/overview/overview_6_interferometry.rst b/docs/overview/overview_6_interferometry.rst index fe2b83170..aa434a1a4 100644 --- a/docs/overview/overview_6_interferometry.rst +++ b/docs/overview/overview_6_interferometry.rst @@ -202,7 +202,8 @@ directly fitting the visibilities in the uv-plane. .. code-block:: python pixelization = al.Pixelization( - mesh=al.mesh.DelaunayMagnification(shape=(30, 30)), + image_mesh=al.image_mesh.Overlay(shape=(30, 30)), + mesh=al.mesh.Delaunay(), regularization=al.reg.Constant(coefficient=1.0), ) diff --git a/test_autolens/aggregator/test_aggregator_fit_imaging.py b/test_autolens/aggregator/test_aggregator_fit_imaging.py index 45ee828c5..1218b3ddd 100644 --- a/test_autolens/aggregator/test_aggregator_fit_imaging.py +++ b/test_autolens/aggregator/test_aggregator_fit_imaging.py @@ -95,3 +95,31 @@ def test__fit_imaging_all_above_weight_gen(analysis_imaging_7x7, samples, model) assert i == 2 clean(database_file=database_file) + + +def test__fit_imaging__adapt_images( + analysis_imaging_7x7, samples, model, adapt_images_7x7 +): + agg = aggregator_from( + database_file=database_file, + analysis=analysis_imaging_7x7, + model=model, + samples=samples, + ) + + fit_agg = al.agg.FitImagingAgg(aggregator=agg) + fit_pdf_gen = fit_agg.randomly_drawn_via_pdf_gen_from(total_samples=2) + + i = 0 + + for fit_gen in fit_pdf_gen: + for fit_list in fit_gen: + i += 1 + assert ( + list(fit_list[0].adapt_images.galaxy_image_dict.values())[0] + == list(adapt_images_7x7.galaxy_name_image_dict.values())[0] + ).all() + + assert i == 2 + + clean(database_file=database_file) diff --git a/test_autolens/aggregator/test_aggregator_fit_interferometer.py b/test_autolens/aggregator/test_aggregator_fit_interferometer.py index 98acfc669..5fa55d559 100644 --- a/test_autolens/aggregator/test_aggregator_fit_interferometer.py +++ b/test_autolens/aggregator/test_aggregator_fit_interferometer.py @@ -101,3 +101,31 @@ def test__fit_interferometer_all_above_weight_gen( assert i == 2 clean(database_file=database_file) + + +def test__fit_interferometer__adapt_images( + analysis_interferometer_7, samples, model, adapt_images_7x7 +): + agg = aggregator_from( + database_file=database_file, + analysis=analysis_interferometer_7, + model=model, + samples=samples, + ) + + fit_agg = al.agg.FitInterferometerAgg(aggregator=agg) + fit_pdf_gen = fit_agg.randomly_drawn_via_pdf_gen_from(total_samples=2) + + i = 0 + + for fit_gen in fit_pdf_gen: + for fit_list in fit_gen: + i += 1 + assert ( + list(fit_list[0].adapt_images.galaxy_image_dict.values())[0] + == list(adapt_images_7x7.galaxy_name_image_dict.values())[0] + ).all() + + assert i == 2 + + clean(database_file=database_file) diff --git a/test_autolens/aggregator/test_aggregator_tracer.py b/test_autolens/aggregator/test_aggregator_tracer.py index 41e0b6e3b..fc5c57b00 100644 --- a/test_autolens/aggregator/test_aggregator_tracer.py +++ b/test_autolens/aggregator/test_aggregator_tracer.py @@ -7,16 +7,11 @@ def test__tracer_randomly_drawn_via_pdf_gen_from( masked_imaging_7x7, - adapt_model_image_7x7, - adapt_galaxy_image_path_dict_7x7, samples, model, ): analysis = al.AnalysisImaging(dataset=masked_imaging_7x7) - analysis.adapt_model_image = adapt_model_image_7x7 - analysis.adapt_galaxy_image_path_dict = adapt_galaxy_image_path_dict_7x7 - agg = aggregator_from( database_file=database_file, analysis=analysis, diff --git a/test_autolens/analysis/test_analysis.py b/test_autolens/analysis/test_analysis.py index 3d632df5a..ebbdf96d4 100644 --- a/test_autolens/analysis/test_analysis.py +++ b/test_autolens/analysis/test_analysis.py @@ -78,7 +78,9 @@ def test__tracer_for_instance__subhalo_redshift_rescale_used(analysis_imaging_7x assert tracer.galaxies[1].mass.centre == pytest.approx((-0.19959, -0.39919), 1.0e-4) -def test__use_border__determines_if_border_pixel_relocation_is_used(masked_imaging_7x7): +def test__relocate_pix_border__determines_if_border_pixel_relocation_is_used( + masked_imaging_7x7, +): pixelization = al.Pixelization( mesh=al.mesh.Rectangular(shape=(3, 3)), regularization=al.reg.Constant(coefficient=1.0), @@ -99,16 +101,13 @@ def test__use_border__determines_if_border_pixel_relocation_is_used(masked_imagi analysis = al.AnalysisImaging( dataset=masked_imaging_7x7, - settings_pixelization=al.SettingsPixelization(use_border=True), + settings_inversion=al.SettingsInversion(relocate_pix_border=True), ) analysis.dataset.grid_pixelization[4] = np.array([[500.0, 0.0]]) instance = model.instance_from_unit_vector([]) - tracer = analysis.tracer_via_instance_from(instance=instance) - fit = analysis.fit_imaging_via_tracer_from( - tracer=tracer, - ) + fit = analysis.fit_from(instance=instance) assert fit.inversion.linear_obj_list[0].source_plane_data_grid[4][ 0 @@ -119,15 +118,14 @@ def test__use_border__determines_if_border_pixel_relocation_is_used(masked_imagi analysis = al.AnalysisImaging( dataset=masked_imaging_7x7, - settings_pixelization=al.SettingsPixelization(use_border=False), + settings_inversion=al.SettingsInversion(relocate_pix_border=False), ) analysis.dataset.grid_pixelization[4] = np.array([300.0, 0.0]) instance = model.instance_from_unit_vector([]) - tracer = analysis.tracer_via_instance_from(instance=instance) - fit = analysis.fit_imaging_via_tracer_from( - tracer=tracer, + fit = analysis.fit_from( + instance=instance, ) assert fit.inversion.linear_obj_list[0].source_plane_data_grid[4][ diff --git a/test_autolens/analysis/test_result.py b/test_autolens/analysis/test_result.py index 3c3129749..be860d8dd 100644 --- a/test_autolens/analysis/test_result.py +++ b/test_autolens/analysis/test_result.py @@ -366,11 +366,11 @@ def test___image_dict(analysis_imaging_7x7): ) image_dict = result.image_galaxy_dict - assert isinstance(image_dict[("galaxies", "lens")], np.ndarray) - assert isinstance(image_dict[("galaxies", "source")], np.ndarray) + assert isinstance(image_dict[str(("galaxies", "lens"))], np.ndarray) + assert isinstance(image_dict[str(("galaxies", "source"))], np.ndarray) result.instance.galaxies.lens = al.Galaxy(redshift=0.5) image_dict = result.image_galaxy_dict - assert (image_dict[("galaxies", "lens")].native == np.zeros((7, 7))).all() - assert isinstance(image_dict[("galaxies", "source")], np.ndarray) + assert (image_dict[str(("galaxies", "lens"))].native == np.zeros((7, 7))).all() + assert isinstance(image_dict[str(("galaxies", "source"))], np.ndarray) diff --git a/test_autolens/analysis/test_visualizer.py b/test_autolens/analysis/test_visualizer.py index 62fe8feb1..0c977d2f7 100644 --- a/test_autolens/analysis/test_visualizer.py +++ b/test_autolens/analysis/test_visualizer.py @@ -58,12 +58,3 @@ def test__visualizes_image_with_positions__uses_configs( plot_path = path.join(plot_path, "positions") assert path.join(plot_path, "image_with_positions.png") in plot_patch.paths - - -def test__visualize_stochastic_histogram(masked_imaging_7x7, plot_path, plot_patch): - visualizer = vis.Visualizer(visualize_path=plot_path) - - visualizer.visualize_stochastic_histogram( - stochastic_log_likelihoods=[1.0, 2.0, 1.0, 2.0, 3.0, 2.5], max_log_evidence=3.0 - ) - assert path.join(plot_path, "other", "stochastic_histogram.png") in plot_patch.paths diff --git a/test_autolens/config/general.yaml b/test_autolens/config/general.yaml index b4e59f75d..824254fa0 100644 --- a/test_autolens/config/general.yaml +++ b/test_autolens/config/general.yaml @@ -5,15 +5,12 @@ fits: flip_for_ds9: true grid: remove_projected_centre: false - stochastic_histogram_bins: 2 - stochastic_histogram_samples: 2 hpc: hpc_mode: false iterations_per_update: 5000 adapt: adapt_minimum_percent: 0.01 adapt_noise_limit: 100000000.0 - stochastic_outputs: false inversion: check_reconstruction: false # If True, the inversion's reconstruction is checked to ensure the solution of a meshs's mapper is not an invalid solution where the values are all the same. use_positive_only_solver: false # If True, inversion's use a positive-only linear algebra solver by default, which is slower but prevents unphysical negative values in the reconstructed solutuion. diff --git a/test_autolens/config/visualize.yaml b/test_autolens/config/visualize.yaml index a9fd1fbd5..d2ac393a4 100644 --- a/test_autolens/config/visualize.yaml +++ b/test_autolens/config/visualize.yaml @@ -140,8 +140,6 @@ plots: regularization_weights: false residual_map: false subplot_inversion: true - other: - stochastic_histogram: true positions: image_with_positions: true ray_tracing: diff --git a/test_autolens/conftest.py b/test_autolens/conftest.py index 0ded18e14..b4442adec 100644 --- a/test_autolens/conftest.py +++ b/test_autolens/conftest.py @@ -376,14 +376,14 @@ def make_adapt_galaxy_image_0_7x7(): return fixtures.make_adapt_galaxy_image_0_7x7() -@pytest.fixture(name="adapt_model_image_7x7") -def make_adapt_model_image_7x7(): - return fixtures.make_adapt_model_image_7x7() +@pytest.fixture(name="adapt_galaxy_name_image_dict_7x7") +def make_adapt_galaxy_name_image_dict_7x7(): + return fixtures.make_adapt_galaxy_name_image_dict_7x7() -@pytest.fixture(name="adapt_galaxy_image_path_dict_7x7") -def make_adapt_galaxy_image_path_dict_7x7(): - return fixtures.make_adapt_galaxy_image_path_dict_7x7() +@pytest.fixture(name="adapt_images_7x7") +def make_adapt_images_7x7(): + return fixtures.make_adapt_images_7x7() @pytest.fixture(name="include_2d_all") diff --git a/test_autolens/imaging/model/test_analysis_imaging.py b/test_autolens/imaging/model/test_analysis_imaging.py index 0f1f9d30e..e7baf8ce2 100644 --- a/test_autolens/imaging/model/test_analysis_imaging.py +++ b/test_autolens/imaging/model/test_analysis_imaging.py @@ -123,104 +123,6 @@ def test__positions__likelihood_overwrites__changes_likelihood(masked_imaging_7x ) assert analysis_log_likelihood == pytest.approx(-22048700558.9052, 1.0e-4) - -def test__sets_up_adapt_galaxy_images__froms(masked_imaging_7x7): - - adapt_galaxy_image_path_dict = { - ("galaxies", "lens"): al.Array2D.ones(shape_native=(3, 3), pixel_scales=1.0), - ("galaxies", "source"): al.Array2D.full( - fill_value=2.0, shape_native=(3, 3), pixel_scales=1.0 - ), - } - - result = al.m.MockResult( - adapt_galaxy_image_path_dict=adapt_galaxy_image_path_dict, - adapt_model_image=al.Array2D.full( - fill_value=3.0, shape_native=(3, 3), pixel_scales=1.0 - ), - ) - - analysis = al.AnalysisImaging( - dataset=masked_imaging_7x7, adapt_result=result - ) - - assert ( - analysis.adapt_galaxy_image_path_dict[("galaxies", "lens")].native - == np.ones((3, 3)) - ).all() - - assert ( - analysis.adapt_galaxy_image_path_dict[("galaxies", "source")].native - == 2.0 * np.ones((3, 3)) - ).all() - - assert (analysis.adapt_model_image.native == 3.0 * np.ones((3, 3))).all() - - -def test__stochastic_log_likelihoods_for_instance(masked_imaging_7x7): - - lens_adapt_image = al.Array2D.ones(shape_native=(3, 3), pixel_scales=0.1) - lens_adapt_image[4] = 10.0 - source_adapt_image = al.Array2D.ones(shape_native=(3, 3), pixel_scales=0.1) - source_adapt_image[4] = 10.0 - adapt_model_image = al.Array2D.full( - fill_value=0.5, shape_native=(3, 3), pixel_scales=0.1 - ) - - adapt_galaxy_image_path_dict = { - ("galaxies", "lens"): lens_adapt_image, - ("galaxies", "source"): source_adapt_image, - } - - result = al.m.MockResult( - adapt_galaxy_image_path_dict=adapt_galaxy_image_path_dict, - adapt_model_image=adapt_model_image, - ) - - pixelization = al.Pixelization( - image_mesh=al.image_mesh.Overlay(shape=(3, 3)), - mesh=al.mesh.Voronoi() - ) - - galaxies = af.ModelInstance() - galaxies.lens = al.Galaxy( - redshift=0.5, mass=al.mp.IsothermalSph(einstein_radius=1.0) - ) - galaxies.source = al.Galaxy(redshift=1.0, pixelization=pixelization) - - instance = af.ModelInstance() - instance.galaxies = galaxies - - analysis = al.AnalysisImaging( - dataset=masked_imaging_7x7, - adapt_result=result, - settings_lens=al.SettingsLens(stochastic_samples=2), - ) - - stochastic_log_likelihoods = analysis.stochastic_log_likelihoods_via_instance_from( - instance=instance - ) - - assert stochastic_log_likelihoods is None - - pixelization = al.Pixelization( - image_mesh=al.image_mesh.KMeans(pixels=7), - mesh=al.mesh.Voronoi() - ) - - galaxies.source = al.Galaxy(redshift=1.0, pixelization=pixelization) - - instance = af.ModelInstance() - instance.galaxies = galaxies - - stochastic_log_likelihoods = analysis.stochastic_log_likelihoods_via_instance_from( - instance=instance - ) - - assert len(stochastic_log_likelihoods) == 2 - assert stochastic_log_likelihoods[0] != stochastic_log_likelihoods[1] - - def test__profile_log_likelihood_function(masked_imaging_7x7): pixelization = al.Pixelization( diff --git a/test_autolens/imaging/test_fit_imaging.py b/test_autolens/imaging/test_fit_imaging.py index 51b6d9755..be4034837 100644 --- a/test_autolens/imaging/test_fit_imaging.py +++ b/test_autolens/imaging/test_fit_imaging.py @@ -204,6 +204,32 @@ def test__fit_figure_of_merit(masked_imaging_7x7, masked_imaging_covariance_7x7) assert fit.perform_inversion is False assert fit.figure_of_merit == pytest.approx(-3688191.0841, 1.0e-4) + pixelization = al.Pixelization( + image_mesh=al.image_mesh.KMeans(pixels=5), + mesh=al.mesh.Delaunay(), + regularization=al.reg.Constant(coefficient=1.0), + ) + + galaxy_pix = al.Galaxy(redshift=1.0, pixelization=pixelization) + + tracer = al.Tracer.from_galaxies(galaxies=[g0, galaxy_pix]) + + model_image = al.Array2D( + np.full(fill_value=5.0, shape=masked_imaging_7x7.mask.pixels_in_mask), + mask=masked_imaging_7x7.mask, + ) + + adapt_images = al.AdaptImages( + galaxy_image_dict={galaxy_pix: model_image}, + ) + + fit = al.FitImaging( + dataset=masked_imaging_7x7, tracer=tracer, adapt_images=adapt_images + ) + + assert fit.perform_inversion is True + assert fit.figure_of_merit == pytest.approx(-341415.8258823, 1.0e-4) + def test__galaxy_model_image_dict(masked_imaging_7x7): @@ -452,56 +478,6 @@ def test__tracer_linear_light_profiles_to_light_profiles(masked_imaging_7x7): assert tracer.galaxies[1].bulge.intensity == pytest.approx(-371.061130, 1.0e-4) assert tracer.galaxies[2].bulge.intensity == pytest.approx(0.08393533428, 1.0e-4) - -def _test___stochastic_mode__gives_different_log_likelihoods(masked_imaging_7x7): - - pixelization = al.Pixelization( - mesh=al.mesh.VoronoiBrightnessImage(pixels=7), - regularization=al.reg.Constant(coefficient=1.0), - ) - - g0 = al.Galaxy( - redshift=0.5, - pixelization=pixelization, - adapt_model_image=al.Array2D.ones(shape_native=(3, 3), pixel_scales=1.0), - adapt_galaxy_image=al.Array2D.ones(shape_native=(3, 3), pixel_scales=1.0), - ) - - tracer = al.Tracer.from_galaxies(galaxies=[al.Galaxy(redshift=0.5), g0]) - - fit_0 = al.FitImaging( - dataset=masked_imaging_7x7, - tracer=tracer, - settings_pixelization=al.SettingsPixelization(is_stochastic=False), - ) - fit_1 = al.FitImaging( - dataset=masked_imaging_7x7, - tracer=tracer, - settings_pixelization=al.SettingsPixelization(is_stochastic=False), - ) - - assert fit_0.log_evidence == fit_1.log_evidence - - fit_0 = al.FitImaging( - dataset=masked_imaging_7x7, - tracer=tracer, - settings_pixelization=al.SettingsPixelization(is_stochastic=True), - ) - fit_1 = al.FitImaging( - dataset=masked_imaging_7x7, - tracer=tracer, - settings_pixelization=al.SettingsPixelization(is_stochastic=True), - ) - - # Sum 5 stochastic likelihoods to avoid random chance of identical - # pixelizations and therefore likelihoods. - - log_evidence_x5_0 = sum([fit_0.log_evidence for i in range(5)]) - log_evidence_x5_1 = sum([fit_1.log_evidence for i in range(5)]) - - assert log_evidence_x5_0 != log_evidence_x5_1 - - def test__preloads__refit_with_new_preloads(masked_imaging_7x7): g0 = al.Galaxy( diff --git a/test_autolens/interferometer/model/test_analysis_interferometer.py b/test_autolens/interferometer/model/test_analysis_interferometer.py index 4a12700c3..73deb53c5 100644 --- a/test_autolens/interferometer/model/test_analysis_interferometer.py +++ b/test_autolens/interferometer/model/test_analysis_interferometer.py @@ -115,82 +115,6 @@ def test__positions__likelihood_overwrite__changes_likelihood( assert analysis_log_likelihood == pytest.approx(-22048700567.590656, 1.0e-4) -def test__sets_up_adapt_galaxy_images(interferometer_7): - adapt_galaxy_image_path_dict = { - ("galaxies", "lens"): al.Array2D.ones(shape_native=(3, 3), pixel_scales=1.0), - ("galaxies", "source"): al.Array2D.full( - fill_value=2.0, shape_native=(3, 3), pixel_scales=1.0 - ), - } - - result = al.m.MockResult( - adapt_galaxy_image_path_dict=adapt_galaxy_image_path_dict, - adapt_model_image=al.Array2D.full( - fill_value=3.0, shape_native=(3, 3), pixel_scales=1.0 - ), - ) - - analysis = al.AnalysisInterferometer(dataset=interferometer_7, adapt_result=result) - - analysis.set_adapt_dataset(result=result) - - assert ( - analysis.adapt_galaxy_image_path_dict[("galaxies", "lens")].native - == np.ones((3, 3)) - ).all() - - assert ( - analysis.adapt_galaxy_image_path_dict[("galaxies", "source")].native - == 2.0 * np.ones((3, 3)) - ).all() - - assert (analysis.adapt_model_image.native == 3.0 * np.ones((3, 3))).all() - - -def test__stochastic_log_likelihoods_for_instance(interferometer_7): - lens_adapt_image = al.Array2D.ones(shape_native=(3, 3), pixel_scales=0.1) - lens_adapt_image[4] = 10.0 - source_adapt_image = al.Array2D.ones(shape_native=(3, 3), pixel_scales=0.1) - source_adapt_image[4] = 10.0 - adapt_model_image = al.Array2D.full( - fill_value=0.5, shape_native=(3, 3), pixel_scales=0.1 - ) - - adapt_galaxy_image_path_dict = { - ("galaxies", "lens"): lens_adapt_image, - ("galaxies", "source"): source_adapt_image, - } - - result = al.m.MockResult( - adapt_galaxy_image_path_dict=adapt_galaxy_image_path_dict, - adapt_model_image=adapt_model_image, - ) - - analysis = al.AnalysisInterferometer( - dataset=interferometer_7, - settings_lens=al.SettingsLens(stochastic_samples=2), - adapt_result=result, - settings_inversion=al.SettingsInversion(use_w_tilde=False), - ) - - pixelization = al.Pixelization( - image_mesh=al.image_mesh.KMeans(pixels=5), mesh=al.mesh.Voronoi() - ) - - galaxies = af.ModelInstance() - galaxies.source = al.Galaxy(redshift=1.0, pixelization=pixelization) - - instance = af.ModelInstance() - instance.galaxies = galaxies - - log_evidences = analysis.stochastic_log_likelihoods_via_instance_from( - instance=instance - ) - - assert len(log_evidences) == 2 - assert log_evidences[0] != log_evidences[1] - - def test__profile_log_likelihood_function(interferometer_7): pixelization = al.Pixelization( mesh=al.mesh.Rectangular(shape=(3, 3)), diff --git a/test_autolens/interferometer/test_simulate_and_fit_interferometer.py b/test_autolens/interferometer/test_simulate_and_fit_interferometer.py index 47bdce97b..15af413e7 100644 --- a/test_autolens/interferometer/test_simulate_and_fit_interferometer.py +++ b/test_autolens/interferometer/test_simulate_and_fit_interferometer.py @@ -71,7 +71,6 @@ def test__perfect_fit__chi_squared_0(): fit = al.FitInterferometer( dataset=dataset, tracer=tracer, - settings_pixelization=al.SettingsPixelization(use_border=False), settings_inversion=al.SettingsInversion(use_w_tilde=False), ) @@ -95,7 +94,6 @@ def test__perfect_fit__chi_squared_0(): fit = al.FitInterferometer( dataset=dataset, tracer=tracer, - settings_pixelization=al.SettingsPixelization(use_border=False), settings_inversion=al.SettingsInversion(use_w_tilde=False), ) assert abs(fit.chi_squared) < 1.0e-4 @@ -194,7 +192,6 @@ def test__simulate_interferometer_data_and_fit__linear_light_profiles_agree_with fit = al.FitInterferometer( dataset=dataset, tracer=tracer, - settings_pixelization=al.SettingsPixelization(use_border=False), settings_inversion=al.SettingsInversion(use_w_tilde=False), ) @@ -217,7 +214,6 @@ def test__simulate_interferometer_data_and_fit__linear_light_profiles_agree_with fit_linear = al.FitInterferometer( dataset=dataset, tracer=tracer_linear, - settings_pixelization=al.SettingsPixelization(use_border=False), settings_inversion=al.SettingsInversion(use_w_tilde=False), ) @@ -324,7 +320,6 @@ def test__simulate_interferometer_data_and_fit__linear_light_profiles_and_pixeli fit_linear = al.FitInterferometer( dataset=dataset, tracer=tracer_linear, - settings_pixelization=al.SettingsPixelization(use_border=False), settings_inversion=al.SettingsInversion(use_w_tilde=False), ) diff --git a/test_autolens/lens/test_to_inversion.py b/test_autolens/lens/test_to_inversion.py index 10cf38612..3a2755141 100644 --- a/test_autolens/lens/test_to_inversion.py +++ b/test_autolens/lens/test_to_inversion.py @@ -162,29 +162,31 @@ def test__cls_pg_list_from(sub_grid_2d_7x7): def test__adapt_galaxy_image_pg_list(sub_grid_2d_7x7): gal = al.Galaxy(redshift=0.5) - pixelization = al.Pixelization( - mesh=al.m.MockMesh(), regularization=al.m.MockRegularization() - ) - - gal_pix = al.Galaxy(redshift=0.5, pixelization=pixelization) - tracer = al.Tracer.from_galaxies(galaxies=[gal, gal]) tracer_to_inversion = al.TracerToInversion(tracer=tracer) assert tracer_to_inversion.adapt_galaxy_image_pg_list == [[]] + pixelization = al.Pixelization( + mesh=al.m.MockMesh(), regularization=al.m.MockRegularization() + ) + + gal_pix = al.Galaxy(redshift=0.5, pixelization=pixelization) + tracer = al.Tracer.from_galaxies(galaxies=[gal_pix, gal_pix]) tracer_to_inversion = al.TracerToInversion(tracer=tracer) assert tracer_to_inversion.adapt_galaxy_image_pg_list == [[None, None]] - gal_pix = al.Galaxy(redshift=0.5, pixelization=pixelization, adapt_galaxy_image=1) + gal_pix = al.Galaxy(redshift=0.5, pixelization=pixelization) + + adapt_images = al.AdaptImages(galaxy_image_dict={gal_pix: 1}) tracer = al.Tracer.from_galaxies(galaxies=[gal_pix, gal]) - tracer_to_inversion = al.TracerToInversion(tracer=tracer) + tracer_to_inversion = al.TracerToInversion(tracer=tracer, adapt_images=adapt_images) assert tracer_to_inversion.adapt_galaxy_image_pg_list == [[1]] @@ -192,17 +194,21 @@ def test__adapt_galaxy_image_pg_list(sub_grid_2d_7x7): gal1 = al.Galaxy(redshift=0.75) gal2 = al.Galaxy(redshift=1.5) - gal_pix0 = al.Galaxy(redshift=0.5, pixelization=pixelization, adapt_galaxy_image=1) + gal_pix0 = al.Galaxy(redshift=0.5, pixelization=pixelization) + + gal_pix1 = al.Galaxy(redshift=2.0, pixelization=pixelization) - gal_pix1 = al.Galaxy(redshift=2.0, pixelization=pixelization, adapt_galaxy_image=2) + gal_pix2 = al.Galaxy(redshift=2.0, pixelization=pixelization) - gal_pix2 = al.Galaxy(redshift=2.0, pixelization=pixelization, adapt_galaxy_image=3) + adapt_images = al.AdaptImages( + galaxy_image_dict={gal_pix0: 1, gal_pix1: 2, gal_pix2: 3} + ) tracer = al.Tracer.from_galaxies( galaxies=[gal0, gal1, gal2, gal_pix0, gal_pix1, gal_pix2] ) - tracer_to_inversion = al.TracerToInversion(tracer=tracer) + tracer_to_inversion = al.TracerToInversion(tracer=tracer, adapt_images=adapt_images) assert tracer_to_inversion.adapt_galaxy_image_pg_list == [[], [1], [], [], [2, 3]] @@ -448,7 +454,6 @@ def test__inversion_imaging_from(sub_grid_2d_7x7, masked_imaging_7x7): data=masked_imaging_7x7.data, noise_map=masked_imaging_7x7.noise_map, w_tilde=masked_imaging_7x7.w_tilde, - settings_pixelization=al.SettingsPixelization(use_border=False), settings_inversion=al.SettingsInversion(use_w_tilde=False), ) @@ -471,7 +476,6 @@ def test__inversion_imaging_from(sub_grid_2d_7x7, masked_imaging_7x7): data=masked_imaging_7x7.data, noise_map=masked_imaging_7x7.noise_map, w_tilde=masked_imaging_7x7.w_tilde, - settings_pixelization=al.SettingsPixelization(use_border=False), settings_inversion=al.SettingsInversion(use_w_tilde=False), ) @@ -495,7 +499,6 @@ def test__inversion_interferometer_from(sub_grid_2d_7x7, interferometer_7): data=interferometer_7.visibilities, noise_map=interferometer_7.noise_map, w_tilde=None, - settings_pixelization=al.SettingsPixelization(use_border=False), settings_inversion=al.SettingsInversion(use_w_tilde=False), ) @@ -518,7 +521,6 @@ def test__inversion_interferometer_from(sub_grid_2d_7x7, interferometer_7): data=interferometer_7.visibilities, noise_map=interferometer_7.noise_map, w_tilde=None, - settings_pixelization=al.SettingsPixelization(use_border=False), settings_inversion=al.SettingsInversion(use_w_tilde=False), )