def __init__( self, name: str, positions: aa.Grid2DIrregular, noise_map: aa.ValuesIrregular, tracer: Tracer, point_solver: PointSolver, point_profile: Optional[ag.ps.Point] = None, ): """ A lens position fitter, which takes a set of positions (e.g. from a plane in the tracer) and computes \ their maximum separation, such that points which tracer closer to one another have a higher log_likelihood. Parameters ----------- positions : Grid2DIrregular The (y,x) arc-second coordinates of positions which the maximum distance and log_likelihood is computed using. noise_value The noise-value assumed when computing the log likelihood. """ self.name = name if point_profile is None: point_profile = tracer.extract_profile(profile_name=name) self.point_profile = point_profile self.point_solver = point_solver if self.point_profile is None: raise exc.PointExtractionException( f"For the point-source named {name} there was no matching point source profile " f"in the tracer (make sure your tracer's point source name is the same the dataset name." ) self.source_plane_coordinate = self.point_profile.centre if len(tracer.planes) > 2: upper_plane_index = tracer.extract_plane_index_of_profile( profile_name=name) else: upper_plane_index = None model_positions = point_solver.solve( lensing_obj=tracer, source_plane_coordinate=self.source_plane_coordinate, upper_plane_index=upper_plane_index, ) model_positions = model_positions.grid_of_closest_from( grid_pair=positions) super().__init__( data=positions, noise_map=noise_map, model_data=model_positions, mask=None, inversion=None, )
def __init__( self, name: str, fluxes: aa.ValuesIrregular, noise_map: aa.ValuesIrregular, positions: aa.Grid2DIrregular, tracer: Tracer, point_profile: Optional[ag.ps.Point] = None, ): self.tracer = tracer self.name = name self.positions = positions if point_profile is None: point_profile = tracer.extract_profile(profile_name=name) self.point_profile = point_profile if self.point_profile is None: raise exc.PointExtractionException( f"For the point-source named {name} there was no matching point source profile " f"in the tracer (make sure your tracer's point source name is the same the dataset name." ) elif not hasattr(self.point_profile, "flux"): raise exc.PointExtractionException( f"For the point-source named {name} the extracted point source was the " f"class {self.point_profile.__class__.__name__} and therefore does " f"not contain a flux component.") if len(tracer.planes) > 2: upper_plane_index = tracer.extract_plane_index_of_profile( profile_name=name) deflections_func = partial( tracer.deflections_between_planes_from, plane_i=0, plane_j=upper_plane_index, ) else: deflections_func = tracer.deflections_yx_2d_from self.magnifications = abs( self.tracer.magnification_2d_via_hessian_from( grid=positions, deflections_func=deflections_func)) model_fluxes = aa.ValuesIrregular(values=[ magnification * self.point_profile.flux for magnification in self.magnifications ]) super().__init__( data=fluxes, noise_map=noise_map, model_data=model_fluxes, mask=None, inversion=None, )
def tracer_via_instance_from( self, instance: af.ModelInstance, profiling_dict: Optional[Dict] = None ) -> Tracer: """ Create a `Tracer` from the galaxies contained in a model instance. If PyAutoFit's profiling tools are used with the analsyis class, this function may receive a `profiling_dict` which times how long each set of the model-fit takes to perform. Parameters ---------- instance An instance of the model that is fitted to the data by this analysis (whose parameters may have been set via a non-linear search). Returns ------- Tracer An instance of the Tracer class that is used to then fit the dataset. """ if hasattr(instance, "perturbation"): instance.galaxies.subhalo = instance.perturbation # TODO : Need to think about how we do this without building it into the model attribute names. # TODO : A Subhalo class that extends the Galaxy class maybe? if hasattr(instance.galaxies, "subhalo"): subhalo_centre = ray_tracing_util.grid_2d_at_redshift_from( galaxies=instance.galaxies, redshift=instance.galaxies.subhalo.redshift, grid=aa.Grid2DIrregular(grid=[instance.galaxies.subhalo.mass.centre]), cosmology=self.cosmology, ) instance.galaxies.subhalo.mass.centre = tuple(subhalo_centre.in_list[0]) if hasattr(instance, "clumps"): return Tracer.from_galaxies( galaxies=instance.galaxies + instance.clumps, cosmology=self.cosmology, profiling_dict=profiling_dict, ) if hasattr(instance, "cosmology"): cosmology = instance.cosmology else: cosmology = self.cosmology return Tracer.from_galaxies( galaxies=instance.galaxies, cosmology=cosmology, profiling_dict=profiling_dict, )
def __init__( self, positions: aa.Grid2DIrregular, noise_map: aa.ValuesIrregular, tracer: Tracer, ): """ Given a positions dataset, which is a list of positions with names that associated them to model source galaxies, use a `Tracer` to determine the traced coordinate positions in the source-plane. Different children of this abstract class are available which use the traced coordinates to define a chi-squared value in different ways. Parameters ----------- positions : Grid2DIrregular The (y,x) arc-second coordinates of named positions which the log_likelihood is computed using. Positions are paired to galaxies in the `Tracer` using their names. tracer : Tracer The object that defines the ray-tracing of the strong lens system of galaxies. noise_value The noise-value assumed when computing the log likelihood. """ self.positions = positions self.noise_map = noise_map self.source_plane_positions = tracer.traced_grid_list_from( grid=positions)[-1]
def __init__( self, name: str, fluxes: aa.ValuesIrregular, noise_map: aa.ValuesIrregular, positions: aa.Grid2DIrregular, tracer: Tracer, point_profile: Optional[ag.ps.Point] = None, ): super().__init__(dataset=fluxes) self.tracer = tracer self._noise_map = noise_map self.name = name self.positions = positions self.point_profile = (tracer.extract_profile( profile_name=name) if point_profile is None else point_profile) if self.point_profile is None: raise exc.PointExtractionException( f"For the point-source named {name} there was no matching point source profile " f"in the tracer (make sure your tracer's point source name is the same the dataset name." ) elif not hasattr(self.point_profile, "flux"): raise exc.PointExtractionException( f"For the point-source named {name} the extracted point source was the " f"class {self.point_profile.__class__.__name__} and therefore does " f"not contain a flux component.")
def _tracer_from(fit: af.Fit, galaxies: List[ag.Galaxy]) -> Tracer: """ Returns a `Tracer` object from a PyAutoFit database `Fit` object and an instance of galaxies from a non-linear search model-fit. This function adds the `hyper_model_image` and `hyper_galaxy_image_path_dict` to the galaxies before constructing the `Tracer`, if they were used. Parameters ---------- fit A PyAutoFit database Fit object containing the generators of the results of PyAutoGalaxy model-fits. galaxies A list of galaxies corresponding to a sample of a non-linear search and model-fit. Returns ------- Tracer The tracer computed via an instance of galaxies. """ hyper_model_image = fit.value(name="hyper_model_image") hyper_galaxy_image_path_dict = fit.value( name="hyper_galaxy_image_path_dict") galaxies_with_hyper = [] if hyper_galaxy_image_path_dict is not None: galaxy_path_list = [ gal[0] for gal in fit.instance.path_instance_tuples_for_class(ag.Galaxy) ] for (galaxy_path, galaxy) in zip(galaxy_path_list, galaxies): if galaxy_path in hyper_galaxy_image_path_dict: galaxy.hyper_model_image = hyper_model_image galaxy.hyper_galaxy_image = hyper_galaxy_image_path_dict[ galaxy_path] galaxies_with_hyper.append(galaxy) return Tracer.from_galaxies(galaxies=galaxies_with_hyper) return Tracer.from_galaxies(galaxies=galaxies)
def __init__( self, point_dataset: PointDataset, tracer: Tracer, positions_solver: PositionsSolver, ): point_profile = tracer.extract_profile(profile_name=point_dataset.name) try: if isinstance(point_profile, ps.PointSourceChi): self.positions = FitPositionsSource( name=point_dataset.name, positions=point_dataset.positions, noise_map=point_dataset.positions_noise_map, tracer=tracer, point_profile=point_profile, ) else: self.positions = FitPositionsImage( name=point_dataset.name, positions=point_dataset.positions, noise_map=point_dataset.positions_noise_map, positions_solver=positions_solver, tracer=tracer, point_profile=point_profile, ) except exc.PointExtractionException: self.positions = None except (AttributeError, numba.errors.TypingError) as e: raise FitException from e try: self.flux = FitFluxes( name=point_dataset.name, fluxes=point_dataset.fluxes, noise_map=point_dataset.fluxes_noise_map, positions=point_dataset.positions, tracer=tracer, ) except exc.PointExtractionException: self.flux = None
def via_galaxies_from(self, galaxies, grid, name=None): """Simulate imaging data for this data, as follows: 1) Setup the image-plane grid of the Imaging arrays, which defines the coordinates used for the ray-tracing. 2) Use this grid and the lens and source galaxies to setup a tracer, which generates the image of \ the simulated imaging data. 3) Simulate the imaging data, using a special image which ensures edge-effects don't degrade simulator of the telescope optics (e.g. the PSF convolution). 4) Plot the image using Matplotlib, if the plot_imaging bool is True. 5) Output the dataset to .fits format if a dataset_path and data_name are specified. Otherwise, return the simulated \ imaging data instance.""" tracer = Tracer.from_galaxies(galaxies=galaxies) return self.via_tracer_from(tracer=tracer, grid=grid, name=name)
def __init__( self, name: str, positions: aa.Grid2DIrregular, noise_map: aa.ValuesIrregular, tracer: Tracer, point_solver: PointSolver, point_profile: Optional[ag.ps.Point] = None, ): """ A lens position fitter, which takes a set of positions (e.g. from a plane in the tracer) and computes \ their maximum separation, such that points which tracer closer to one another have a higher log_likelihood. Parameters ----------- positions : Grid2DIrregular The (y,x) arc-second coordinates of positions which the maximum distance and log_likelihood is computed using. noise_value The noise-value assumed when computing the log likelihood. """ super().__init__(dataset=positions) self.name = name self._noise_map = noise_map self.tracer = tracer self.point_profile = ( tracer.extract_profile(profile_name=name) if point_profile is None else point_profile ) self.point_solver = point_solver if self.point_profile is None: raise exc.PointExtractionException( f"For the point-source named {name} there was no matching point source profile " f"in the tracer (make sure your tracer's point source name is the same the dataset name." ) self.source_plane_coordinate = self.point_profile.centre
def via_tracer_from(self, tracer: Tracer, grid: aa.type.Grid2DLike, plane_index: int) -> aplt.Visuals2D: """ From a `Tracer` get the attributes that can be plotted and returns them in a `Visuals2D` object. Only attributes with `True` entries in the `Include` object are extracted. From a tracer the following attributes can be extracted for plotting: - origin: the (y,x) origin of the coordinate system used to plot the light object's quantities in 2D. - border: the border of the mask of the grid used to plot the light object's quantities in 2D. - light profile centres: the (y,x) centre of every `LightProfile` in the object. - mass profile centres: the (y,x) centre of every `MassProfile` in the object. - critical curves: the critical curves of all of the tracer's mass profiles combined. - caustics: the caustics of all of the tracer's mass profiles combined. When plotting a `Tracer` it is common for plots to only display quantities corresponding to one plane at a time (e.g. the convergence in the image plane, the source in the source plane). Therefore, quantities are only extracted from one plane, specified by the input `plane_index`. Parameters ---------- tracer The `Tracer` object which has attributes extracted for plotting. grid The 2D grid of (y,x) coordinates used to plot the tracer's quantities in 2D. plane_index The index of the plane in the tracer which is used to extract quantities, as only one plane is plotted at a time. Returns ------- vis.Visuals2D A collection of attributes that can be plotted by a `Plotter` object. """ origin = self.get("origin", value=aa.Grid2DIrregular(grid=[grid.origin])) border = self.get("border", value=grid.mask.border_grid_sub_1.binned) if border is not None and len(border) > 0 and plane_index > 0: border = tracer.traced_grid_2d_list_from(grid=border)[plane_index] light_profile_centres = self.get( "light_profile_centres", tracer.planes[plane_index].extract_attribute( cls=ag.lp.LightProfile, attr_name="centre"), ) mass_profile_centres = self.get( "mass_profile_centres", tracer.planes[plane_index].extract_attribute(cls=ag.mp.MassProfile, attr_name="centre"), ) if plane_index == 0: critical_curves = self.get( "critical_curves", tracer.critical_curves_from(grid=grid), "critical_curves", ) else: critical_curves = None if plane_index == 1: caustics = self.get("caustics", tracer.caustics_from(grid=grid), "caustics") else: caustics = None return self.visuals + self.visuals.__class__( origin=origin, border=border, light_profile_centres=light_profile_centres, mass_profile_centres=mass_profile_centres, critical_curves=critical_curves, caustics=caustics, )