Source code for lenstronomy.GalKin.galkin_shells

import numpy as np
from lenstronomy.GalKin.galkin import Galkin
from lenstronomy.Util import util
from lenstronomy.Util import mask_util
from scipy import signal


[docs] class GalkinShells(Galkin): """Class to calculate velocity dispersion for radial shells in a fast way."""
[docs] def __init__( self, kwargs_model, kwargs_aperture, kwargs_psf, kwargs_cosmo, kwargs_numerics=None, analytic_kinematics=False, ): """ :param kwargs_model: keyword arguments describing the model components :param kwargs_aperture: keyword arguments describing the spectroscopic aperture, see Aperture() class :param kwargs_psf: keyword argument specifying the PSF of the observation :param kwargs_cosmo: keyword arguments that define the cosmology in terms of the angular diameter distances involved :param kwargs_numerics: numerics keyword arguments :param analytic_kinematics: bool, if True uses the analytic kinematic model """ Galkin.__init__( self, kwargs_model=kwargs_model, kwargs_aperture=kwargs_aperture, kwargs_psf=kwargs_psf, kwargs_cosmo=kwargs_cosmo, kwargs_numerics=kwargs_numerics, analytic_kinematics=analytic_kinematics, ) if not self.aperture_type == "IFU_shells": raise ValueError( 'GalkinShells is not supported with aperture_type %s. Only support with "IFU_shells"' % self.aperture_type ) self._r_bins = kwargs_aperture["r_bins"] r_max = np.max(self._r_bins) self._num_pix = 100 # factor of 1.5 to allow outside flux to be convolved into the largest bin self._delta_pix = 1.5 * r_max * 2 / self._num_pix x_grid, y_grid = util.make_grid( num_pix=self._num_pix, delta_pix=self._delta_pix ) self._r_grid = np.sqrt(x_grid**2 + y_grid**2)
[docs] def dispersion_map(self, kwargs_mass, kwargs_light, kwargs_anisotropy, **kwargs): """ :param kwargs_mass: mass model parameters (following lenstronomy lens model conventions) :param kwargs_light: deflector light parameters (following lenstronomy light model conventions) :param kwargs_anisotropy: anisotropy parameters, may vary according to anisotropy type chosen. We refer to the Anisotropy() class for details on the parameters. :return: array of velocity dispersion for each IFU shell [km/s] """ I_R_sigma2, IR = self.numerics._I_R_sigma2_interp( self._r_grid, kwargs_mass, kwargs_light, kwargs_anisotropy ) ir_map = util.array2image(IR) ir_sigma2_map = util.array2image(I_R_sigma2) kernel = self.convolution_kernel( delta_pix=self._delta_pix, num_pix=self._num_pix ) I_R_sigma2_conv = signal.fftconvolve(ir_sigma2_map, kernel, mode="same") I_R_sigma2_conv = util.image2array(I_R_sigma2_conv) I_R_conv = signal.fftconvolve(ir_map, kernel, mode="same") I_R_conv = util.image2array(I_R_conv) # average over radial bins vel_disp_array = [] r_min = self._r_bins[0] for r_max in self._r_bins[1:]: mask = mask_util.mask_shell( self._r_grid, 0, center_x=0, center_y=0, r_in=r_min, r_out=r_max ) vel_disp = np.sum(I_R_sigma2_conv * mask) / np.sum( I_R_conv * mask ) # luminosity weighted average vel_disp_array.append(vel_disp) r_min = r_max self.numerics.delete_cache() return np.sqrt(np.array(vel_disp_array)) / 1000