Source code for caustics.lenses.nfw

# mypy: disable-error-code="operator,union-attr,dict-item"
from typing import Optional, Union, Annotated

from caskade import forward, Param

from ..backend_obj import ArrayLike
from .base import ThinLens, NameType, CosmologyType, ZType
from . import func

DELTA = 200.0

__all__ = ("NFW",)


[docs] class NFW(ThinLens): """ NFW lens class. This class models a lens using the Navarro-Frenk-White (NFW) profile. The NFW profile is a spatial density profile of dark matter halo that arises in cosmological simulations. Attributes ----------- z_l: Optional[ArrayLike] Redshift of the lens. Default is None. *Unit: unitless* z_s: Optional[ArrayLike] Redshift of the source. Default is None. *Unit: unitless* x0: Optional[ArrayLike] x-coordinate of the lens center in the lens plane. Default is None. *Unit: arcsec* y0: Optional[ArrayLike] y-coordinate of the lens center in the lens plane. Default is None. *Unit: arcsec* mass: Optional[ArrayLike] Mass of the lens. Default is None. *Unit: Msun* c: Optional[ArrayLike] Concentration parameter of the lens. Default is None. *Unit: unitless* s: float Softening parameter to avoid singularities at the center of the lens. Default is 0.0. *Unit: arcsec* Methods ------- get_scale_radius Returns the scale radius of the lens. get_scale_density Returns the scale density of the lens. get_convergence_s Returns the dimensionless surface mass density of the lens. deflection_angle Computes the deflection angle. convergence Computes the convergence (dimensionless surface mass density). potential Computes the lensing potential. """ _null_params = { "x0": 0.0, "y0": 0.0, "mass": 1e13, "c": 5.0, } def __init__( self, cosmology: CosmologyType, z_l: ZType = None, z_s: ZType = None, x0: Annotated[ Optional[Union[ArrayLike, float]], "X coordinate of the lens center", True ] = None, y0: Annotated[ Optional[Union[ArrayLike, float]], "Y coordinate of the lens center", True ] = None, mass: Annotated[ Optional[Union[ArrayLike, float]], "Mass of the lens", True ] = None, c: Annotated[ Optional[Union[ArrayLike, float]], "Concentration parameter of the lens", True, ] = None, s: Annotated[ float, "Softening parameter to avoid singularities at the center of the lens", ] = 0.0, name: NameType = None, ): """ Initialize an instance of the NFW lens class. Parameters ---------- name: str Name of the lens instance. cosmology: Cosmology An instance of the Cosmology class which contains information about the cosmological model and parameters. z_l: Optional[Union[ArrayLike, float]] Redshift of the lens. Default is None. *Unit: unitless* x0: Optional[Union[ArrayLike, float]] x-coordinate of the lens center in the lens plane. Default is None. *Unit: arcsec* y0: Optional[Union[ArrayLike, float]] y-coordinate of the lens center in the lens plane. Default is None. *Unit: arcsec* mass: Optional[Union[ArrayLike, float]] Mass of the lens. Default is None. *Unit: Msun* c: Optional[Union[ArrayLike, float]] Concentration parameter of the lens. Default is None. *Unit: unitless* s: float Softening parameter to avoid singularities at the center of the lens. Default is 0.0. *Unit: arcsec* """ super().__init__(cosmology, z_l, name=name, z_s=z_s) self.x0 = Param("x0", x0, shape=(), units="arcsec") self.y0 = Param("y0", y0, shape=(), units="arcsec") self.mass = Param("mass", mass, shape=(), units="Msun") self.c = Param("c", c, shape=(), units="unitless") self.s = s
[docs] @forward def get_scale_radius( self, z_l: Annotated[ArrayLike, "Param"], mass: Annotated[ArrayLike, "Param"], c: Annotated[ArrayLike, "Param"], ) -> ArrayLike: """ Calculate the scale radius of the lens. Parameters ---------- z_l: ArrayLike Redshift of the lens. *Unit: unitless* mass: ArrayLike Mass of the lens. *Unit: Msun* c: ArrayLike Concentration parameter of the lens. *Unit: unitless* Returns ------- ArrayLike The scale radius of the lens in Mpc. *Unit: Mpc* """ critical_density = self.cosmology.critical_density(z_l) return func.scale_radius_nfw(critical_density, mass, c, DELTA)
[docs] @forward def get_scale_density( self, z_l: Annotated[ArrayLike, "Param"], c: Annotated[ArrayLike, "Param"], ) -> ArrayLike: """ Calculate the scale density of the lens. Parameters ---------- z_l: ArrayLike Redshift of the lens. *Unit: unitless* c: ArrayLike Concentration parameter of the lens. *Unit: unitless* Returns ------- ArrayLike The scale density of the lens in solar masses per Mpc cubed. *Unit: Msun/Mpc^3* """ critical_density = self.cosmology.critical_density(z_l) return func.scale_density_nfw(critical_density, c, DELTA)
[docs] @forward def physical_deflection_angle( self, x: ArrayLike, y: ArrayLike, z_l: Annotated[ArrayLike, "Param"], x0: Annotated[ArrayLike, "Param"], y0: Annotated[ArrayLike, "Param"], mass: Annotated[ArrayLike, "Param"], c: Annotated[ArrayLike, "Param"], ) -> tuple[ArrayLike, ArrayLike]: """ Compute the physical deflection angle. Parameters ---------- x: ArrayLike x-coordinates in the lens plane. *Unit: arcsec* y: ArrayLike y-coordinates in the lens plane. *Unit: arcsec* Returns ------- x_component: ArrayLike The x-component of the reduced deflection angle. *Unit: arcsec* y_component: ArrayLike The y-component of the reduced deflection angle. *Unit: arcsec* """ d_l = self.cosmology.angular_diameter_distance(z_l) critical_density = self.cosmology.critical_density(z_l) return func.physical_deflection_angle_nfw( x0, y0, mass, c, critical_density, d_l, x, y, DELTA=DELTA, s=self.s )
[docs] @forward def reduced_deflection_angle(self, x, y, z_s, z_l): d_s = self.cosmology.angular_diameter_distance(z_s) d_ls = self.cosmology.angular_diameter_distance_z1z2(z_l, z_s) deflection_angle_x, deflection_angle_y = self.physical_deflection_angle(x, y) return func.reduced_from_physical_deflection_angle( deflection_angle_x, deflection_angle_y, d_s, d_ls )
[docs] @forward def convergence( self, x: ArrayLike, y: ArrayLike, z_s: Annotated[ArrayLike, "Param"], z_l: Annotated[ArrayLike, "Param"], x0: Annotated[ArrayLike, "Param"], y0: Annotated[ArrayLike, "Param"], mass: Annotated[ArrayLike, "Param"], c: Annotated[ArrayLike, "Param"], ) -> ArrayLike: """ Compute the convergence (dimensionless surface mass density). Parameters ---------- x: ArrayLike x-coordinates in the lens plane. *Unit: arcsec* y: ArrayLike y-coordinates in the lens plane. *Unit: arcsec* Returns ------- ArrayLike The convergence (dimensionless surface mass density). *Unit: unitless* """ critical_surface_density = self.cosmology.critical_surface_density(z_l, z_s) critical_density = self.cosmology.critical_density(z_l) d_l = self.cosmology.angular_diameter_distance(z_l) return func.convergence_nfw( critical_surface_density, critical_density, x0, y0, mass, c, x, y, d_l, DELTA=DELTA, s=self.s, )
[docs] @forward def potential( self, x: ArrayLike, y: ArrayLike, z_s: Annotated[ArrayLike, "Param"], z_l: Annotated[ArrayLike, "Param"], x0: Annotated[ArrayLike, "Param"], y0: Annotated[ArrayLike, "Param"], mass: Annotated[ArrayLike, "Param"], c: Annotated[ArrayLike, "Param"], ) -> ArrayLike: """ Compute the lensing potential. Parameters ---------- x: ArrayLike x-coordinates in the lens plane. *Unit: arcsec* y: ArrayLike y-coordinates in the lens plane. *Unit: arcsec* Returns ------- ArrayLike The lensing potential. *Unit: arcsec^2* """ critical_surface_density = self.cosmology.critical_surface_density(z_l, z_s) critical_density = self.cosmology.critical_density(z_l) d_l = self.cosmology.angular_diameter_distance(z_l) return func.potential_nfw( critical_surface_density, critical_density, x0, y0, mass, c, d_l, x, y, DELTA=DELTA, s=self.s, )