Source code for lenstronomy.GalKin.galkin_multiobservation

from lenstronomy.GalKin.observation import GalkinObservation
from lenstronomy.GalKin.galkin_model import GalkinModel

import numpy as np

__all__ = ["GalkinMultiObservation"]


[docs] class GalkinMultiObservation(GalkinModel): """Class to efficiently model the velocity dispersion measurement of a set of different observations with individual apertures and seeing conditions for a given lens. The main difference to the Galkin main class is that it feeds in list of observational settings. Does not work with IFU observations (yet) """
[docs] def __init__( self, kwargs_model, kwargs_aperture_list, kwargs_psf_list, kwargs_cosmo, kwargs_numerics=None, analytic_kinematics=False, ): """ :param kwargs_model: keyword arguments describing the model components :param kwargs_aperture_list: list of keyword arguments describing the spectroscopic aperture, see Aperture() class :param kwargs_psf_list: list of 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 - see GalkinModel :param analytic_kinematics: bool, if True uses the analytic kinematic model """ GalkinModel.__init__( self, kwargs_model, kwargs_cosmo, kwargs_numerics=kwargs_numerics, analytic_kinematics=analytic_kinematics, ) self._observation_list = [] self._num_observations = len(kwargs_aperture_list) for i in range(self._num_observations): self._observation_list.append( GalkinObservation( kwargs_aperture=kwargs_aperture_list[i], kwargs_psf=kwargs_psf_list[i], backend="galkin", ) )
[docs] def dispersion_map( self, kwargs_mass, kwargs_light, kwargs_anisotropy, num_kin_sampling=1000, num_psf_sampling=100, ): """Computes the velocity dispersion in each Integral Field Unit. :param kwargs_mass: keyword arguments of the mass model :param kwargs_light: keyword argument of the light model :param kwargs_anisotropy: anisotropy keyword arguments :param num_kin_sampling: int, number of draws from a kinematic prediction of a LOS :param num_psf_sampling: int, number of displacements/render from a spectra to be displaced on the IFU :return: ordered array of velocity dispersions [km/s] for each observation """ # draw from light profile (3d and 2d option) # compute kinematics of it (analytic or numerical) # displace it n-times # add it and keep track of how many draws are added on each segment # compute average in each segment # return value per segment sigma2_R_sum = np.zeros(self._num_observations) count_draws = np.zeros(self._num_observations) for i in range(0, num_kin_sampling): r, R, x, y = self.numerics.draw_light(kwargs_light) sigma2_IR, IR = self.numerics.sigma_s2( r, R, kwargs_mass, kwargs_light, kwargs_anisotropy ) for obs_index, observation in enumerate(self._observation_list): for k in range(0, num_psf_sampling): x_, y_ = observation.displace_psf(x, y) bool_ap, _ = observation.aperture_select(x_, y_) if bool_ap is True: sigma2_R_sum[obs_index] += sigma2_IR count_draws[obs_index] += IR sigma_s2_average = sigma2_R_sum / count_draws # apply unit conversion from arc seconds and deflections to physical velocity dispersion in (km/s) self.numerics.delete_cache() return np.sqrt(sigma_s2_average) / 1000.0 # in units of km/s