Source code for slsim.Deflectors.DeflectorPopulation.all_lens_galaxies

import numpy as np
import numpy.random as random
from slsim.Lenses.selection import object_cut
from slsim.Deflectors.MassLightConnection.velocity_dispersion import (
    vel_disp_abundance_matching,
)
from slsim.Deflectors.DeflectorPopulation.elliptical_lens_galaxies import (
    elliptical_projected_eccentricity,
)
from slsim.Deflectors.DeflectorPopulation.deflectors_base import DeflectorsBase
from astropy.table import vstack
from slsim.Util.param_util import catalog_with_angular_size_in_arcsec
from slsim.Deflectors.deflector import Deflector


[docs] class AllLensGalaxies(DeflectorsBase): """Class describing all-type galaxies.""" def __init__( self, red_galaxy_list, blue_galaxy_list, kwargs_cut, kwargs_mass2light, cosmo, sky_area, gamma_pl=None, catalog_type="skypy", ): """ :param red_galaxy_list: list of dictionary with elliptical galaxy parameters (supporting skypy pipelines) :type red_galaxy_list: astropy.Table :param blue_galaxy_list: list of dictionary with spiral galaxy parameters (supporting skypy pipelines) :type blue_galaxy_list: astropy.Table :param kwargs_cut: cuts in parameters: band, band_mag, z_min, z_max :type kwargs_cut: dict :param kwargs_mass2light: mass-to-light relation :param cosmo: astropy.cosmology instance :type sky_area: `~astropy.units.Quantity` :param sky_area: Sky area over which galaxies are sampled. Must be in units of solid angle. :param gamma_pl: power law slope in EPL profile. :type gamma_pl: A float or a dictionary with given mean and standard deviation of a density slope for gaussian distribution or minimum and maximum values of gamma for uniform distribution. eg: gamma_pl=2.1, gamma_pl={"mean": a, "std_dev": b}, gamma_pl={"gamma_min": c, "gamma_max": d} :param catalog_type: type of the catalog. If user is using deflector catalog other than generated from skypy pipeline, we require them to provide angular size of the galaxy in arcsec and specify catalog_type as None. Otherwise, by default, this class considers deflector catalog is generated using skypy pipeline. :type catalog_type: str. "skypy" or None. """ red_galaxy_list = catalog_with_angular_size_in_arcsec( galaxy_catalog=red_galaxy_list, input_catalog_type=catalog_type ) blue_galaxy_list = catalog_with_angular_size_in_arcsec( galaxy_catalog=blue_galaxy_list, input_catalog_type=catalog_type ) red_column_names = red_galaxy_list.colnames if "galaxy_type" not in red_column_names: red_galaxy_list["galaxy_type"] = "red" blue_column_names = blue_galaxy_list.colnames if "galaxy_type" not in blue_column_names: blue_galaxy_list["galaxy_type"] = "blue" galaxy_list = vstack([red_galaxy_list, blue_galaxy_list]) super().__init__( deflector_table=galaxy_list, kwargs_cut=kwargs_cut, cosmo=cosmo, sky_area=sky_area, gamma_pl=gamma_pl, ) n = len(galaxy_list) column_names = galaxy_list.colnames if "vel_disp" not in column_names: galaxy_list["vel_disp"] = -np.ones(n) if "e1_light" not in column_names or "e2_light" not in column_names: galaxy_list["e1_light"] = -np.ones(n) galaxy_list["e2_light"] = -np.ones(n) if "e1_mass" not in column_names or "e2_mass" not in column_names: galaxy_list["e1_mass"] = -np.ones(n) galaxy_list["e2_mass"] = -np.ones(n) if "n_sersic" not in column_names: galaxy_list["n_sersic"] = -np.ones(n) galaxy_list = fill_table(galaxy_list) self._f_vel_disp = vel_disp_abundance_matching( galaxy_list, z_max=0.5, sky_area=sky_area, cosmo=cosmo ) self._galaxy_select = object_cut(galaxy_list, **kwargs_cut) self._num_select = len(self._galaxy_select) # Assign velocity dispersions through abundance matching if the "vel_disp" column is missing if "vel_disp" not in column_names: self._galaxy_select["vel_disp"] = self._f_vel_disp( np.log10(self._galaxy_select["stellar_mass"]) ) # TODO: random reshuffle of matched list
[docs] def deflector_number(self): """ :return: number of deflectors after applied cuts """ number = self._num_select return number
[docs] def draw_deflector(self): """ :return: dictionary of complete parameterization of a deflector """ index = random.randint(0, self._num_select - 1) deflector = self._galaxy_select[index] if deflector["e1_light"] == -1 or deflector["e2_light"] == -1: e1_light, e2_light, e1_mass, e2_mass = elliptical_projected_eccentricity( **deflector ) deflector["e1_light"] = e1_light deflector["e2_light"] = e2_light deflector["e1_mass"] = e1_mass deflector["e2_mass"] = e2_mass if deflector["n_sersic"] == -1: deflector["n_sersic"] = 4 # TODO make a better estimate with scatter deflector_class = Deflector(deflector_type=self.deflector_profile, **deflector) return deflector_class
[docs] def fill_table(galaxy_list): """ :param galaxy_list: ~Astropy.Table instance :return: table with additional columns """ n = len(galaxy_list) column_names = galaxy_list.colnames if "vel_disp" not in column_names: galaxy_list["vel_disp"] = -np.ones(n) if "e1_light" not in column_names or "e2_light" not in column_names: galaxy_list["e1_light"] = -np.ones(n) galaxy_list["e2_light"] = -np.ones(n) if "e1_mass" not in column_names or "e2_mass" not in column_names: galaxy_list["e1_mass"] = -np.ones(n) galaxy_list["e2_mass"] = -np.ones(n) if "n_sersic" not in column_names: galaxy_list["n_sersic"] = -np.ones(n) return galaxy_list