diff --git a/autogalaxy/__init__.py b/autogalaxy/__init__.py index 1a7efbbfa..bcc593e34 100644 --- a/autogalaxy/__init__.py +++ b/autogalaxy/__init__.py @@ -6,6 +6,7 @@ from autoconf.dictable import from_dict, from_json, output_to_json, to_dict from autoarray.dataset import preprocess # noqa + # from autoarray.dataset.interferometer.w_tilde import ( # load_curvature_preload_if_compatible, # ) diff --git a/autogalaxy/analysis/analysis/analysis.py b/autogalaxy/analysis/analysis/analysis.py index 438ac013c..5d94bba4c 100644 --- a/autogalaxy/analysis/analysis/analysis.py +++ b/autogalaxy/analysis/analysis/analysis.py @@ -7,7 +7,7 @@ from autogalaxy.galaxy.galaxy import Galaxy from autogalaxy.galaxy.galaxies import Galaxies -from autogalaxy.cosmology.lensing import LensingCosmology +from autogalaxy.cosmology.model import LensingCosmology logger = logging.getLogger(__name__) @@ -36,7 +36,7 @@ def __init__( The Cosmology assumed for this analysis. """ - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 self.cosmology = cosmology or Planck15() self.preloads = preloads diff --git a/autogalaxy/analysis/analysis/dataset.py b/autogalaxy/analysis/analysis/dataset.py index 54e7b48bd..f2ad68159 100644 --- a/autogalaxy/analysis/analysis/dataset.py +++ b/autogalaxy/analysis/analysis/dataset.py @@ -8,7 +8,7 @@ import autoarray as aa from autogalaxy.analysis.adapt_images.adapt_images import AdaptImages -from autogalaxy.cosmology.lensing import LensingCosmology +from autogalaxy.cosmology.model import LensingCosmology from autogalaxy.analysis.analysis.analysis import Analysis from autogalaxy.analysis.result import ResultDataset diff --git a/autogalaxy/config/priors/cosmology.yaml b/autogalaxy/config/priors/cosmology.yaml index 656941bba..e9feba055 100644 --- a/autogalaxy/config/priors/cosmology.yaml +++ b/autogalaxy/config/priors/cosmology.yaml @@ -1,54 +1,10 @@ -model.LambdaCDMWrap: +model.FlatLambdaCDM: H0: type: Constant value: 67.66 Om0: type: Constant value: 0.30966 - Ode0: - type: Constant - value: 0.69034 - Tcmb0: - type: Constant - value: 2.7255 - Neff: - type: Constant - value: 3.046 - m_nu: - type: Constant - value: 0.06 - Ob0: - type: Constant - value: 0.04897 -model.FlatLambdaCDMWrap: - H0: - type: Constant - value: 67.66 - Om0: - type: Constant - value: 0.30966 - Tcmb0: - type: Constant - value: 2.7255 - Neff: - type: Constant - value: 3.046 - m_nu: - type: Constant - value: 0.06 - Ob0: - type: Constant - value: 0.04897 -model.FlatwCDMWrap: - H0: - type: Constant - value: 67.66 - Om0: - type: Constant - value: 0.30966 - w0: - type: Constant - value: -1.0 Tcmb0: type: Constant value: 2.7255 diff --git a/autogalaxy/convert.py b/autogalaxy/convert.py index 5bda71120..ff1c2a17d 100644 --- a/autogalaxy/convert.py +++ b/autogalaxy/convert.py @@ -331,9 +331,12 @@ def multipole_comps_from( ------- The multipole component parameters. """ - from astropy import units + # Degrees -> radians conversion + deg_to_rad = xp.asarray(np.pi / 180.0) - multipole_comp_0 = k_m * xp.sin(phi_m * float(m) * units.deg.to(units.rad)) - multipole_comp_1 = k_m * xp.cos(phi_m * float(m) * units.deg.to(units.rad)) + angle = phi_m * float(m) * deg_to_rad - return (multipole_comp_0, multipole_comp_1) + multipole_comp_0 = k_m * xp.sin(angle) + multipole_comp_1 = k_m * xp.cos(angle) + + return multipole_comp_0, multipole_comp_1 diff --git a/autogalaxy/cosmology/__init__.py b/autogalaxy/cosmology/__init__.py index 26f887402..4c4090146 100644 --- a/autogalaxy/cosmology/__init__.py +++ b/autogalaxy/cosmology/__init__.py @@ -1,3 +1 @@ -from .lensing import LensingCosmology -from .wrap import Planck15 -from .model import FlatwCDMWrap, FlatLambdaCDMWrap +from .model import FlatLambdaCDM, Planck15, LensingCosmology diff --git a/autogalaxy/cosmology/lensing.py b/autogalaxy/cosmology/lensing.py deleted file mode 100644 index 5823c6d9d..000000000 --- a/autogalaxy/cosmology/lensing.py +++ /dev/null @@ -1,346 +0,0 @@ -import math -import numpy as np - - -class LensingCosmology: - """ - Class containing specific functions for performing gravitational lensing cosmology calculations. - - By inheriting from the astropy `cosmo.FLRW` class this provides many additional methods for performing cosmological - calculations. - """ - - def __init__(self): - - from astropy.cosmology import FLRW - - self._cosmo = FLRW() - - def arcsec_per_kpc_from(self, redshift: float) -> float: - """ - Angular separation in arcsec corresponding to a proper kpc at redshift `z`. - - For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. - This function therefore returns only the value of the astropy function it wraps, omitting the units instance. - - Parameters - ---------- - redshift - Input redshift from which the angular separation is calculated at. - """ - return self.arcsec_per_kpc_proper(z=redshift).value - - def kpc_per_arcsec_from(self, redshift: float) -> float: - """ - Separation in transverse proper kpc corresponding to an arcminute at redshift `z`. - - For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. - This function therefore returns only the value of the astropy function it wraps, omitting the units instance. - - Parameters - ---------- - redshift - Input redshift from which the transverse proper kpc value is calculated at. - """ - return 1.0 / self.arcsec_per_kpc_proper(z=redshift).value - - def angular_diameter_distance_to_earth_in_kpc_from(self, redshift: float) -> float: - """ - Angular diameter distance from the input `redshift` to redshift zero (e.g. us, the observer on earth) in - kiloparsecs. - - This gives the proper (sometimes called 'physical') transverse distance corresponding to an angle of 1 radian - for an object at redshift `z`. - - Weinberg, 1972, pp 421-424; Weedman, 1986, pp 65-67; Peebles, 1993, pp 325-327. - - For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. - This function therefore returns only the value of the astropy function it wraps, omitting the units instance. - - Parameters - ---------- - redshift - Input redshift from which the angular diameter distance to Earth is calculated. - """ - angular_diameter_distance_kpc = self.angular_diameter_distance(z=redshift).to( - "kpc" - ) - - return angular_diameter_distance_kpc.value - - def angular_diameter_distance_between_redshifts_in_kpc_from( - self, redshift_0: float, redshift_1: float - ) -> float: - """ - Angular diameter distance from an input `redshift_0` to another input `redshift_1`. - - For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. - This function therefore returns only the value of the astropy function it wraps, omitting the units instance. - - Parameters - ---------- - redshift_0 - Redshift from which the angular diameter distance to the other redshift is calculated. - redshift_1 - Redshift from which the angular diameter distance to the other redshift is calculated. - """ - angular_diameter_distance_between_redshifts_kpc = ( - self.angular_diameter_distance_z1z2(redshift_0, redshift_1).to("kpc") - ) - - return angular_diameter_distance_between_redshifts_kpc.value - - def cosmic_average_density_from(self, redshift: float) -> float: - """ - Critical density of the Universe at an input `redshift` in units of solar masses. - - For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. - This function therefore returns only the value of the astropy function it wraps, omitting the units instance. - - Parameters - ---------- - redshift - Redshift at which the critiical density in solMass of the Universe is calculated. - """ - - cosmic_average_density_kpc = ( - self.critical_density(z=redshift).to("solMass / kpc^3").value - ) - - kpc_per_arcsec = self.kpc_per_arcsec_from(redshift=redshift) - - return cosmic_average_density_kpc * kpc_per_arcsec**3.0 - - def cosmic_average_density_solar_mass_per_kpc3_from(self, redshift: float) -> float: - """ - Critical density of the Universe at an input `redshift` in units of solar masses per kiloparsecs**3. - - For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. - This function therefore returns only the value of the astropy function it wraps, omitting the units instance. - - Parameters - ---------- - redshift - Redshift at which the critiical density in solMass/kpc^3 of the Universe is calculated. - """ - cosmic_average_density_kpc = ( - self.critical_density(z=redshift).to("solMass / kpc^3").value - ) - - return cosmic_average_density_kpc - - def critical_surface_density_between_redshifts_from( - self, redshift_0: float, redshift_1: float - ) -> float: - """ - The critical surface density for lensing, often written as $\sigma_{cr}$, is given by: - - critical_surface_density = (c^2 * D_s) / (4 * pi * G * D_ls * D_l) - - c = speed of light - G = Newton's gravity constant - D_s = angular_diameter_distance_of_source_redshift_to_earth - D_ls = angular_diameter_distance_of_lens_redshift_to_source_redshift - D_l = angular_diameter_distance_of_lens_redshift_to_earth - - This function returns the critical surface density in units of solar masses, which are convenient units for - converting the inferred masses of a model from angular units (e.g. dimensionless units inferred from - data in arcseconds) to solar masses. - - Parameters - ---------- - redshift_0 - The redshift of the first strong lens galaxy (E.g. the lens galaxy) for which the critical surface - density is calculated. - redshift_1 - The redshift of the second strong lens galaxy (E.g. the lens galaxy) for which the critical surface - density is calculated. - """ - critical_surface_density_kpc = ( - self.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( - redshift_0=redshift_0, redshift_1=redshift_1 - ) - ) - - kpc_per_arcsec = self.kpc_per_arcsec_from(redshift=redshift_0) - - return critical_surface_density_kpc * kpc_per_arcsec**2.0 - - def critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( - self, redshift_0: float, redshift_1: float - ) -> float: - """ - The critical surface density for lensing, often written as $\sigma_{cr}$, is given by: - - critical_surface_density = (c^2 * D_s) / (4 * pi * G * D_ls * D_l) - - c = speed of light - G = Newton's gravity constant - D_s = Angular diameter distance of source redshift to earth - D_ls = Angular diameter distance of lens redshift to source redshift - D_l = Angular diameter distance of lens redshift to earth - - This function returns the critical surface density in units of solar masses / kpc^2, which are convenient - units for converting the inferred masses of a model from angular units (e.g. dimensionless units inferred - from data in arcseconds) to solar masses. - - Parameters - ---------- - redshift_0 - The redshift of the first strong lens galaxy (E.g. the lens galaxy) for which the critical surface - density is calculated. - redshift_1 - The redshift of the second strong lens galaxy (E.g. the lens galaxy) for which the critical surface - density is calculated. - """ - from astropy import constants - - const = constants.c.to("kpc / s") ** 2.0 / ( - 4 * math.pi * constants.G.to("kpc3 / (solMass s2)") - ) - - angular_diameter_distance_of_redshift_0_to_earth_kpc = ( - self.angular_diameter_distance_to_earth_in_kpc_from(redshift=redshift_0) - ) - - angular_diameter_distance_of_redshift_1_to_earth_kpc = ( - self.angular_diameter_distance_to_earth_in_kpc_from(redshift=redshift_1) - ) - - angular_diameter_distance_between_redshifts_kpc = ( - self.angular_diameter_distance_between_redshifts_in_kpc_from( - redshift_0=redshift_0, redshift_1=redshift_1 - ) - ) - - return ( - const - * angular_diameter_distance_of_redshift_1_to_earth_kpc - / ( - angular_diameter_distance_between_redshifts_kpc - * angular_diameter_distance_of_redshift_0_to_earth_kpc - ) - ).value - - def scaling_factor_between_redshifts_from( - self, redshift_0: float, redshift_1: float, redshift_final: float - ) -> float: - """ - For strong lens systems with more than 2 planes, the deflection angles between different planes must be scaled - by the angular diameter distances between the planes in order to properly perform multi-plane ray-tracing. This - function computes the factor to scale deflections between `redshift_0` and `reshift_final`, to deflections between - `redshift_0` and `redshift_1`. - - The second redshift should be strictly larger than the first. The scaling factor is unity when `redshift_1` - is `redshift_final`, and 0 when `redshift_0` is equal to `redshift_1`. - - For a system with a first lens galaxy l0 at `redshift_0`, second lens galaxy l1 at `redshift_1` and final - source galaxy at `redshift_final` this scaling factor is given by: - - (D_l0l1 * D_s) / (D_l1* D_l0s) - - The critical surface density for lensing, often written as $\\sigma_{cr}$, is given by: - - critical_surface_density = (c^2 * D_s) / (4 * pi * G * D_ls * D_l) - - D_l0l1 = Angular diameter distance of first lens redshift to second lens redshift. - D_s = Angular diameter distance of source redshift to earth - D_l1 = Angular diameter distance of second lens redshift to Earth. - D_l0s = Angular diameter distance of first lens redshift to source redshift - - For systems with more planes this scaling factor is computed multiple times for the different redshift - combinations and applied recursively when scaling the deflection angles. - - Parameters - ---------- - redshift_0 - The redshift of the first strong lens galaxy. - redshift_1 - The redshift of the second strong lens galaxy. - redshift_final - The redshift of the source galaxy. - """ - angular_diameter_distance_between_redshifts_0_and_1 = ( - self.angular_diameter_distance_z1z2(z1=redshift_0, z2=redshift_1) - .to("kpc") - .value - ) - - angular_diameter_distance_to_redshift_final = ( - self.angular_diameter_distance(z=redshift_final).to("kpc").value - ) - - angular_diameter_distance_of_redshift_1_to_earth = ( - self.angular_diameter_distance(z=redshift_1).to("kpc").value - ) - - angular_diameter_distance_between_redshift_0_and_final = ( - self.angular_diameter_distance_z1z2(z1=redshift_0, z2=redshift_final) - .to("kpc") - .value - ) - - return ( - angular_diameter_distance_between_redshifts_0_and_1 - * angular_diameter_distance_to_redshift_final - ) / ( - angular_diameter_distance_of_redshift_1_to_earth - * angular_diameter_distance_between_redshift_0_and_final - ) - - def velocity_dispersion_from( - self, redshift_0: float, redshift_1: float, einstein_radius: float - ) -> float: - """ - For a strong lens galaxy with an Einstien radius in arcseconds, the corresponding velocity dispersion of the - lens galaxy can be computed (assuming an isothermal mass distribution). - - The velocity dispersion is given by: - - velocity dispersion = (c * R_Ein * D_s) / (4 * pi * D_l * D_ls) - - c = speed of light - D_s = Angular diameter distance of source redshift to earth - D_ls = Angular diameter distance of lens redshift to source redshift - D_l = Angular diameter distance of lens redshift to earth - - Parameters - ---------- - redshift_0 - The redshift of the first strong lens galaxy (the lens). - redshift_1 - The redshift of the second strong lens galaxy (the source). - """ - from astropy import constants - - const = constants.c.to("kpc / s") - - angular_diameter_distance_to_redshift_0_kpc = ( - self.angular_diameter_distance_to_earth_in_kpc_from(redshift=redshift_1) - ) - - angular_diameter_distance_to_redshift_1_kpc = ( - self.angular_diameter_distance_to_earth_in_kpc_from(redshift=redshift_1) - ) - - angular_diameter_distance_between_redshifts_kpc = ( - self.angular_diameter_distance_between_redshifts_in_kpc_from( - redshift_0=redshift_0, redshift_1=redshift_1 - ) - ) - - kpc_per_arcsec = self.kpc_per_arcsec_from(redshift=redshift_0) - - einstein_radius_kpc = einstein_radius * kpc_per_arcsec - - velocity_dispersion_kpc = const * np.sqrt( - (einstein_radius_kpc * angular_diameter_distance_to_redshift_1_kpc) - / ( - 4 - * np.pi - * angular_diameter_distance_to_redshift_0_kpc - * angular_diameter_distance_between_redshifts_kpc - ) - ) - - return velocity_dispersion_kpc.to("km/s").value diff --git a/autogalaxy/cosmology/model.py b/autogalaxy/cosmology/model.py index 2e30a529b..419c8eb5c 100644 --- a/autogalaxy/cosmology/model.py +++ b/autogalaxy/cosmology/model.py @@ -1,127 +1,412 @@ -from astropy import cosmology as cosmo +import numpy as np -from autogalaxy.cosmology.lensing import LensingCosmology +class LensingCosmology: + """ + Class containing specific functions for performing gravitational lensing cosmology calculations. -class LambdaCDMWrap(cosmo.LambdaCDM, LensingCosmology): - def __init__( - self, - H0: float = 67.66, - Om0: float = 0.30966, - Ode0: float = 0.69034, - Tcmb0: float = 2.7255, - Neff: float = 3.046, - m_nu: float = 0.06, - Ob0: float = 0.04897, - ): + This version is JAX-compatible by using an explicit `xp` backend (NumPy or jax.numpy). + """ + + def arcsec_per_kpc_proper(self, z: float, xp=np) -> float: + """ + Angular separation in arcsec corresponding to 1 proper kpc at redshift z. + + This matches astropy.cosmology.arcsec_per_kpc_proper. + + Proper transverse distance uses the angular diameter distance D_A(z): + + arcsec_per_kpc_proper = 206264.806247 / D_A(z) + + where D_A(z) is in kpc. """ - A wrapper for the astropy `LambdaCDM` cosmology class, which allows it to be used for modeling such - that the cosmological parameters are free parameters which can be fitted for. - The interface of this class is the same as the astropy `LambdaCDM` class, it simply overwrites the - __init__ method and inherits from it in a way that ensures **PyAutoFit** can compose a model from it - without issue. + angular_diameter_distance_kpc = self.angular_diameter_distance_kpc_z1z2( + 0.0, z, xp=xp + ) + + return xp.asarray(206264.806247) / angular_diameter_distance_kpc + + def kpc_proper_per_arcsec(self, z: float, xp=np) -> float: + """ + Proper transverse separation in kpc corresponding to 1 arcsec at redshift z. + + This matches the inverse of astropy.cosmology.arcsec_per_kpc_proper: + + kpc_proper_per_arcsec = D_A(z) / 206264.806247 + """ + + angular_diameter_distance_kpc = self.angular_diameter_distance_kpc_z1z2( + 0.0, z, xp=xp + ) + + return angular_diameter_distance_kpc / xp.asarray(206264.806247) + + def arcsec_per_kpc_from(self, redshift: float, xp=np) -> float: + """ + Angular separation in arcsec corresponding to a proper kpc at redshift `z`. + + For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. + + This is a thin convenience wrapper around `arcsec_per_kpc_proper`. + """ + return self.arcsec_per_kpc_proper(z=redshift, xp=xp) + + def kpc_per_arcsec_from(self, redshift: float, xp=np) -> float: + """ + Separation in transverse proper kpc corresponding to an arcsec at redshift `z`. - The class also inherits from `LensingCosmology`, which is a class that provides additional functionality - for calculating lensing specific quantities in the cosmology. + For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. + + This is a thin convenience wrapper around `kpc_proper_per_arcsec`. + """ + return self.kpc_proper_per_arcsec(z=redshift, xp=xp) + + def angular_diameter_distance_to_earth_in_kpc_from( + self, redshift: float, xp=np + ) -> float: + """ + Angular diameter distance from the input `redshift` to redshift zero (e.g. us, the observer on earth) in + kiloparsecs. + + This gives the proper (sometimes called 'physical') transverse distance corresponding to an angle of 1 radian + for an object at redshift `z`. + + Weinberg, 1972, pp 421-424; Weedman, 1986, pp 65-67; Peebles, 1993, pp 325-327. + + For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. + This function therefore returns only the value of the astropy function it wraps, omitting the units instance. Parameters ---------- - H0 - The Hubble constant at z=0. - Om0 - The total matter density at z=0. - Ode0 - The dark energy density at z=0. - Tcmb0 - The CMB temperature at z=0. - Neff - The effective number of neutrinos. - m_nu - The sum of the neutrino masses. - Ob0 - The baryon density at z=0. + redshift + Input redshift from which the angular diameter distance to Earth is calculated. """ - super().__init__( - H0=H0, - Om0=Om0, - Ode0=Ode0, - Tcmb0=Tcmb0, - Neff=Neff, - m_nu=m_nu, - Ob0=Ob0, - name="FlatLambdaCDM", + return self.angular_diameter_distance_kpc_z1z2(0.0, redshift, xp=xp) + + def angular_diameter_distance_between_redshifts_in_kpc_from( + self, redshift_0: float, redshift_1: float, xp=np + ) -> float: + """ + Angular diameter distance from an input `redshift_0` to another input `redshift_1`. + + For simplicity, **PyAutoLens** internally uses only certain units to perform lensing cosmology calculations. + This function therefore returns only the value of the astropy function it wraps, omitting the units instance. + + Parameters + ---------- + redshift_0 + Redshift from which the angular diameter distance to the other redshift is calculated. + redshift_1 + Redshift from which the angular diameter distance to the other redshift is calculated. + """ + return self.angular_diameter_distance_kpc_z1z2(redshift_0, redshift_1, xp=xp) + + def cosmic_average_density_from(self, redshift: float, xp=np): + """ + Critical density of the Universe at redshift z in units of solar masses, + scaled into arcsec-based internal lensing units. + + Parameters + ---------- + redshift + Redshift at which the critiical density in solMass of the Universe is calculated. + """ + + rho_kpc3 = self.cosmic_average_density_solar_mass_per_kpc3_from(redshift, xp=xp) + kpc_per_arcsec = self.kpc_per_arcsec_from(redshift, xp=xp) + return rho_kpc3 * kpc_per_arcsec**3 + + def cosmic_average_density_solar_mass_per_kpc3_from( + self, + redshift: float, + xp=np, + ): + """ + Critical density of the Universe at redshift z in units of Msun / kpc^3. + + JAX / NumPy compatible via `xp`. + + Computes: + + rho_c(z) = 3 H(z)^2 / (8 pi G) + + Returns physical density (not scaled into arcsec units). + """ + + # ----------------------------- + # Physical constants + # ----------------------------- + + # Gravitational constant in kpc^3 / (Msun s^2) + G = xp.asarray(4.30091e-6) # kpc (km/s)^2 / Msun + G = G / xp.asarray((3.085677581e16) ** 2) + + # H0 in km/s/Mpc → convert to 1/s + H0_km_s_Mpc = xp.asarray(self.H0) + H0_s = H0_km_s_Mpc / xp.asarray(3.085677581e19) + + # Dimensionless expansion factor + Ez = self.E(redshift, xp=xp) + + # H(z) in 1/s + Hz = H0_s * Ez + + # ----------------------------- + # Critical density in Msun/kpc^3 + # ----------------------------- + + rho_crit = (3.0 * Hz**2) / (8.0 * xp.pi * G) + + return rho_crit + + def critical_density(self, z: float, xp=np): + """ + Critical density of the Universe at redshift z, returned in Msun / kpc^3. + + This is an xp (NumPy / JAX) drop-in for the Astropy method: + astropy.cosmology.FLRW.critical_density(z) + + Astropy returns g/cm^3, but in AutoLens you were immediately converting to: + solMass / kpc^3 + + So this function returns Msun / kpc^3 directly. + + Requires: + self.H0 (km/s/Mpc) + self.E(z, xp=xp) where E(z) = H(z)/H0 + """ + + z = xp.asarray(z) + + # H0 in km/s/Mpc -> 1/s + # 1 Mpc = 3.085677581e19 km + H0_s = xp.asarray(self.H0) / xp.asarray(3.085677581e19) + + # H(z) in 1/s + Hz = H0_s * self.E(z, xp=xp) + + # Gravitational constant G in kpc^3 / (Msun s^2) + # Start from: G = 4.30091e-6 kpc (km/s)^2 / Msun + # Convert (km/s)^2 -> (kpc/s)^2 by dividing by (km per kpc)^2 + km_per_kpc = xp.asarray(3.085677581e16) + G = xp.asarray(4.30091e-6) / (km_per_kpc**2) + + # rho_c = 3 H(z)^2 / (8 pi G) [Msun / kpc^3] + return (xp.asarray(3.0) * Hz**2) / (xp.asarray(8.0) * xp.pi * G) + + def critical_surface_density_between_redshifts_from( + self, + redshift_0: float, + redshift_1: float, + xp=np, + ): + """ + Critical surface density scaled into AutoLens angular units (Msun / arcsec^2). + + This is: + Sigma_crit_arcsec2 = Sigma_crit_kpc2 * (kpc_per_arcsec(z_l))^2 + """ + sigma_crit_kpc2 = ( + self.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( + redshift_0=redshift_0, redshift_1=redshift_1, xp=xp + ) ) + kpc_per_arcsec = self.kpc_per_arcsec_from(redshift=redshift_0, xp=xp) -class FlatLambdaCDMWrap(cosmo.FlatLambdaCDM, LensingCosmology): - def __init__( + return sigma_crit_kpc2 * kpc_per_arcsec**2.0 + + def critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( self, - H0: float = 67.66, - Om0: float = 0.30966, - Tcmb0: float = 2.7255, - Neff: float = 3.046, - m_nu: float = 0.06, - Ob0: float = 0.04897, + redshift_0: float, + redshift_1: float, + xp=np, + ): + """ + Critical surface density in physical units (Msun / kpc^2): + + Sigma_crit = (c^2 / (4*pi*G)) * D_s / (D_l * D_ls) + + Distances must be angular diameter distances in kpc. + + JAX/NumPy compatible via `xp` (pass `jax.numpy` as xp). + """ + + # Distances in kpc + D_l_kpc = self.angular_diameter_distance_to_earth_in_kpc_from( + redshift=redshift_0, xp=xp + ) + D_s_kpc = self.angular_diameter_distance_to_earth_in_kpc_from( + redshift=redshift_1, xp=xp + ) + D_ls_kpc = self.angular_diameter_distance_between_redshifts_in_kpc_from( + redshift_0=redshift_0, redshift_1=redshift_1, xp=xp + ) + + # kpc -> m + kpc_to_m = xp.asarray(3.085677581491367e19) + D_l = D_l_kpc * kpc_to_m + D_s = D_s_kpc * kpc_to_m + D_ls = D_ls_kpc * kpc_to_m + + # SI constants + c = xp.asarray(299792458.0) # m/s + G = xp.asarray(6.67430e-11) # m^3/(kg s^2) + Msun = xp.asarray(1.98847e30) # kg + + # Sigma_crit in kg / m^2 + prefac = (c * c) / (xp.asarray(4.0) * xp.pi * G) + sigma_SI = prefac * D_s / (D_l * D_ls) + + # kg/m^2 -> Msun/kpc^2 + sigma = sigma_SI * (kpc_to_m * kpc_to_m) / Msun + + return xp.where(D_ls_kpc == xp.asarray(0.0), xp.asarray(np.inf), sigma) + + def scaling_factor_between_redshifts_from( + self, + redshift_0: float, + redshift_1: float, + redshift_final: float, + xp=np, ): """ - A wrapper for the astropy `FlatLambdaCDM` cosmology class, which allows it to be used for modeling such - that the cosmological parameters are free parameters which can be fitted for. + For strong lens systems with more than 2 planes, the deflection angles between different planes must be scaled + by the angular diameter distances between the planes in order to properly perform multi-plane ray-tracing. This + function computes the factor to scale deflections between `redshift_0` and `reshift_final`, to deflections between + `redshift_0` and `redshift_1`. + + The second redshift should be strictly larger than the first. The scaling factor is unity when `redshift_1` + is `redshift_final`, and 0 when `redshift_0` is equal to `redshift_1`. + + For a system with a first lens galaxy l0 at `redshift_0`, second lens galaxy l1 at `redshift_1` and final + source galaxy at `redshift_final` this scaling factor is given by: - The interface of this class is the same as the astropy `FlatLambdaCDM` class, it simply overwrites the - __init__ method and inherits from it in a way that ensures **PyAutoFit** can compose a model from it - without issue. + (D_l0l1 * D_s) / (D_l1* D_l0s) - The class also inherits from `LensingCosmology`, which is a class that provides additional functionality - for calculating lensing specific quantities in the cosmology. + The critical surface density for lensing, often written as $\\sigma_{cr}$, is given by: + + critical_surface_density = (c^2 * D_s) / (4 * pi * G * D_ls * D_l) + + D_l0l1 = Angular diameter distance of first lens redshift to second lens redshift. + D_s = Angular diameter distance of source redshift to earth + D_l1 = Angular diameter distance of second lens redshift to Earth. + D_l0s = Angular diameter distance of first lens redshift to source redshift + + For systems with more planes this scaling factor is computed multiple times for the different redshift + combinations and applied recursively when scaling the deflection angles. Parameters ---------- - H0 - The Hubble constant at z=0. - Om0 - The total matter density at z=0. - Tcmb0 - The CMB temperature at z=0. - Neff - The effective number of neutrinos. - m_nu - The sum of the neutrino masses. - Ob0 - The baryon density at z=0. + redshift_0 + The redshift of the first strong lens galaxy (the first lens plane). + redshift_1 + The redshift of the second strong lens galaxy (the second lens plane). + redshift_final + The redshift of the final source galaxy (the final source plane). """ - super().__init__( - H0=H0, - Om0=Om0, - Tcmb0=Tcmb0, - Neff=Neff, - m_nu=m_nu, - Ob0=Ob0, - name="FlatLambdaCDM", + + # D_l0l1 : between lens plane 0 and lens plane 1 + D_l0l1 = self.angular_diameter_distance_between_redshifts_in_kpc_from( + redshift_0=redshift_0, + redshift_1=redshift_1, + xp=xp, + ) + + # D_s : observer to final source plane + D_s = self.angular_diameter_distance_to_earth_in_kpc_from( + redshift=redshift_final, + xp=xp, ) + # D_l1 : observer to lens plane 1 + D_l1 = self.angular_diameter_distance_to_earth_in_kpc_from( + redshift=redshift_1, + xp=xp, + ) + + # D_l0s : between lens plane 0 and final source plane + D_l0s = self.angular_diameter_distance_between_redshifts_in_kpc_from( + redshift_0=redshift_0, + redshift_1=redshift_final, + xp=xp, + ) + + return (D_l0l1 * D_s) / (D_l1 * D_l0s) + + def velocity_dispersion_from( + self, redshift_0: float, redshift_1: float, einstein_radius: float, xp=np + ) -> float: + """ + For a strong lens galaxy with an Einstein radius in arcseconds, the corresponding velocity dispersion of the + lens galaxy can be computed (assuming an isothermal mass distribution). + + The velocity dispersion is given by: + + sigma_v = c * sqrt((R_Ein * D_s) / (4 * pi * D_l * D_ls)) -class FlatwCDMWrap(cosmo.FlatwCDM, LensingCosmology): + c = speed of light + D_s = Angular diameter distance of source redshift to earth + D_ls = Angular diameter distance of lens redshift to source redshift + D_l = Angular diameter distance of lens redshift to earth + + Parameters + ---------- + redshift_0 + The redshift of the first strong lens galaxy (the lens). + redshift_1 + The redshift of the second strong lens galaxy (the source). + """ + + # Speed of light in km / s + c_km_s = xp.asarray(299792.458) + + # Angular diameter distances in kpc + D_l = self.angular_diameter_distance_to_earth_in_kpc_from( + redshift=redshift_0, xp=xp + ) + + D_s = self.angular_diameter_distance_to_earth_in_kpc_from( + redshift=redshift_1, xp=xp + ) + + D_ls = self.angular_diameter_distance_between_redshifts_in_kpc_from( + redshift_0=redshift_0, redshift_1=redshift_1, xp=xp + ) + + # Convert Einstein radius to kpc + kpc_per_arcsec = self.kpc_per_arcsec_from(redshift=redshift_0, xp=xp) + R_ein_kpc = xp.asarray(einstein_radius) * kpc_per_arcsec + + # Velocity dispersion (km/s) + sigma_v = c_km_s * xp.sqrt( + (R_ein_kpc * D_s) / (xp.asarray(4.0) * xp.pi * D_l * D_ls) + ) + + return sigma_v + + +class FlatLambdaCDM(LensingCosmology): def __init__( self, H0: float = 67.66, Om0: float = 0.30966, - w0: float = -1.0, Tcmb0: float = 2.7255, Neff: float = 3.046, - m_nu: float = 0.06, + m_nu: float = 0.0, Ob0: float = 0.04897, ): """ - A wrapper for the astropy `FlatwCDM` cosmology class, which allows it to be used for modeling such - that the cosmological parameters are free parameters which can be fitted for. + A JAX-compatible implementation of the FlatLambdaCDM cosmology model, which allows it to be used for + modeling such that the cosmological parameters are free parameters which can be fitted for. - The interface of this class is the same as the astropy `FlatwCDM` class, it simply overwrites the - __init__ method and inherits from it in a way that ensures **PyAutoFit** can compose a model from it - without issue. + This is a custom implementation designed to work with both NumPy and JAX backends, enabling automatic + differentiation and GPU acceleration when needed. The interface and parameter naming conventions follow + the astropy `FlatLambdaCDM` class for compatibility. - The class also inherits from `LensingCosmology`, which is a class that provides additional functionality - for calculating lensing specific quantities in the cosmology. + The class inherits from `LensingCosmology`, which provides additional functionality for calculating + lensing specific quantities in the cosmology. Parameters ---------- @@ -129,8 +414,6 @@ def __init__( The Hubble constant at z=0. Om0 The total matter density at z=0. - w0 - The dark energy equation of state at z=0. Tcmb0 The CMB temperature at z=0. Neff @@ -140,13 +423,264 @@ def __init__( Ob0 The baryon density at z=0. """ + self.H0 = H0 + self.Om0 = Om0 + self.Tcmb0 = Tcmb0 + self.Neff = Neff + self.m_nu = m_nu + self.Ob0 = Ob0 + + # Make ΛCDM a special case of wCDM + self.w0 = -1.0 + + @staticmethod + def _simpson_1d(y, x, xp=np): + """ + Composite Simpson's rule on a 1D grid. + + Requirements: + - x is 1D, evenly spaced + - len(x) is odd (i.e. number of intervals is even) + + Works with numpy or jax.numpy passed as xp. + """ + n = x.shape[0] + if (n % 2) == 0: + raise ValueError( + "Simpson's rule requires an odd number of samples (even number of intervals)." + ) + + h = (x[-1] - x[0]) / (n - 1) + + # y0 + yN + s = y[0] + y[-1] + + # 4 * sum of odd indices + s = s + 4.0 * xp.sum(y[1:-1:2]) + + # 2 * sum of even indices (excluding endpoints) + s = s + 2.0 * xp.sum(y[2:-1:2]) + + return (h / 3.0) * s + + def _m_nu_sum_eV(self, xp=np): + m = xp.asarray(getattr(self, "m_nu", 0.0)) + if getattr(m, "ndim", 0) == 0: + # scalar means per-species mass (astropy convention) + n = int(np.floor(float(getattr(self, "Neff", 3.046)))) + return m * xp.asarray(float(n)) + return xp.sum(m) + + def _radiation_and_massive_nu_densities(self, h, xp=np): + """ + Returns (Or0, Onu_m0) where: + - Or0 is photons + *massless* neutrino radiation (dimensionless today) + - Onu_m0 is massive neutrino density today treated as matter-like (dimensionless today) + + Uses a simple split: N_eff_massless = Neff - n_massive. + """ + Tcmb = xp.asarray(self.Tcmb0) + Ogamma_h2 = xp.asarray(2.469e-5) * (Tcmb / xp.asarray(2.7255)) ** 4 + Ogamma0 = Ogamma_h2 / (h * h) + + # Massive neutrinos: Omega_nu h^2 ≈ sum(m_nu)/93.14 eV + m_nu = getattr(self, "m_nu", 0.0) + m_arr = xp.asarray(m_nu) + if getattr(m_arr, "ndim", 0) == 0: + # interpret scalar as total sum (your current convention) + m_sum = m_arr + n_massive = xp.asarray(1.0) if m_arr > 0 else xp.asarray(0.0) + else: + m_sum = xp.sum(m_arr) + n_massive = xp.sum(m_arr > xp.asarray(0.0)) + + Onu_m_h2 = m_sum / xp.asarray(93.14) + Onu_m0 = Onu_m_h2 / (h * h) + + # Only the *massless* share of Neff contributes as radiation if we're separately adding massive nu matter + Neff = xp.asarray(self.Neff) + Neff_massless = xp.maximum(Neff - n_massive, xp.asarray(0.0)) + Onu_rad0 = Ogamma0 * xp.asarray(0.2271) * Neff_massless + + Or0 = Ogamma0 + Onu_rad0 + return Or0, Onu_m0 + + def angular_diameter_distance_kpc_z1z2( + self, + z1: float, + z2: float, + n_steps: int = 8193, # odd by default + xp=np, + ): + """ + D_A(z1,z2) in kpc for flat wCDM using Simpson's rule. + + Includes: + - photons via Tcmb0 + - neutrinos split into: + * massive part from m_nu (approx matter-like today) + * massless part from Neff, with the number of massive species subtracted to avoid double-counting + + Notes: + - Flat universe: Omega_k = 0 + - Dark energy equation of state constant w0 + """ + # Ensure odd number of samples for Simpson (safe: n_steps is a Python int) + if (n_steps % 2) == 0: + n_steps += 1 + + z1a = xp.asarray(z1) + z2a = xp.asarray(z2) + same = z1a == z2a + + c_km_s = xp.asarray(299792.458) + + H0 = xp.asarray(self.H0) + h = H0 / xp.asarray(100.0) + + Om0 = xp.asarray(self.Om0) + w0 = xp.asarray(self.w0) + + # ---- photons ---- + Tcmb = xp.asarray(getattr(self, "Tcmb0", 0.0)) + Ogamma_h2 = xp.asarray(2.469e-5) * (Tcmb / xp.asarray(2.7255)) ** 4 + Ogamma0 = Ogamma_h2 / (h * h) + + # ---- massive neutrinos (approx matter-like today) ---- + m_nu_sum = self._m_nu_sum_eV(xp=xp) + Onu_m_h2 = m_nu_sum / xp.asarray(93.14) + Onu_m0 = Onu_m_h2 / (h * h) + + # ---- massless neutrino radiation via Neff (avoid double-counting) ---- + Neff = xp.asarray(getattr(self, "Neff", 0.0)) + + m_nu = getattr(self, "m_nu", 0.0) + m_arr = xp.asarray(m_nu) + + if getattr(m_arr, "ndim", 0) == 0: + n_massive = xp.where( + m_arr > xp.asarray(0.0), xp.asarray(1.0), xp.asarray(0.0) + ) + else: + n_massive = xp.sum(m_arr > xp.asarray(0.0)) + + Neff_massless = xp.maximum(Neff - n_massive, xp.asarray(0.0)) + + Onu_rad0 = Ogamma0 * xp.asarray(0.2271) * Neff_massless + Or0 = Ogamma0 + Onu_rad0 + + # ---- flatness: Omega_de ---- + Ode0 = xp.asarray(1.0) - Om0 - Or0 - Onu_m0 + + def E_local(z): + zp1 = xp.asarray(1.0) + z + return xp.sqrt( + (Om0 + Onu_m0) * zp1**3 + + Or0 * zp1**4 + + Ode0 * zp1 ** (xp.asarray(3.0) * (xp.asarray(1.0) + w0)) + ) + + z_grid = xp.linspace(z1a, z2a, n_steps) + integrand = xp.asarray(1.0) / E_local(z_grid) + + integral = self._simpson_1d(integrand, z_grid, xp=xp) + + Dc_Mpc = (c_km_s / H0) * integral + Da_Mpc = Dc_Mpc / (xp.asarray(1.0) + z2a) + Da_kpc = Da_Mpc * xp.asarray(1.0e3) + + return xp.where(same, xp.asarray(0.0), Da_kpc) + + def E(self, z: float, xp=np): + """ + Dimensionless Hubble parameter E(z) = H(z) / H0. + + JAX/NumPy compatible via `xp` (pass `jax.numpy` as xp). + + Components: + - Photons: Omega_gamma from Tcmb0 + - Neutrinos: + * massive part from m_nu (approx matter-like today) + * massless part from Neff, but we subtract the number of massive species to avoid double-counting + - Dark energy: constant w0, with Omega_de set by flatness + """ + + z = xp.asarray(z) + + H0 = xp.asarray(self.H0) + h = H0 / xp.asarray(100.0) + + Om0 = xp.asarray(self.Om0) + w0 = xp.asarray(getattr(self, "w0", -1.0)) + + # ---- photons ---- + Tcmb = xp.asarray(getattr(self, "Tcmb0", 0.0)) + Ogamma_h2 = xp.asarray(2.469e-5) * (Tcmb / xp.asarray(2.7255)) ** 4 + Ogamma0 = Ogamma_h2 / (h * h) + + # ---- massive neutrinos (approx matter-like today) ---- + # NOTE: _m_nu_sum_eV should follow YOUR convention (scalar=total, list=sum, etc.) + m_nu_sum = self._m_nu_sum_eV(xp=xp) + Onu_m_h2 = m_nu_sum / xp.asarray(93.14) + Onu_m0 = Onu_m_h2 / (h * h) + + # ---- massless neutrino radiation via Neff (avoid double-counting) ---- + # Approx: subtract number of massive species from Neff + Neff = xp.asarray(getattr(self, "Neff", 0.0)) + + m_nu = getattr(self, "m_nu", 0.0) + m_arr = xp.asarray(m_nu) + + if getattr(m_arr, "ndim", 0) == 0: + n_massive = xp.where( + m_arr > xp.asarray(0.0), xp.asarray(1.0), xp.asarray(0.0) + ) + else: + n_massive = xp.sum(m_arr > xp.asarray(0.0)) + + Neff_massless = xp.maximum(Neff - n_massive, xp.asarray(0.0)) + + Onu_rad0 = Ogamma0 * xp.asarray(0.2271) * Neff_massless + Or0 = Ogamma0 + Onu_rad0 + + # ---- flatness: Omega_de ---- + Ode0 = xp.asarray(1.0) - Om0 - Or0 - Onu_m0 + + zp1 = xp.asarray(1.0) + z + + Ez2 = ( + (Om0 + Onu_m0) * zp1**3 + + Or0 * zp1**4 + + Ode0 * zp1 ** (xp.asarray(3.0) * (xp.asarray(1.0) + w0)) + ) + + return xp.sqrt(Ez2) + + def Om(self, z: float, xp=np): + """ + Matter density parameter at redshift z: Omega_m(z). + + JAX / NumPy compatible via `xp`. + + For flat models using your E(z): + Om(z) = Om0 (1+z)^3 / E(z)^2 + """ + z = xp.asarray(z) + zp1 = xp.asarray(1.0) + z + + Ez = self.E(z, xp=xp) + return xp.asarray(self.Om0) * zp1**3 / (Ez * Ez) + + +class Planck15(FlatLambdaCDM): + + def __init__(self): + super().__init__( - H0=H0, - Om0=Om0, - w0=w0, - Tcmb0=Tcmb0, - Neff=Neff, - m_nu=m_nu, - Ob0=Ob0, - name="FlatwCDM", + H0=67.74, + Om0=0.3075, + Tcmb0=2.7255, + Neff=3.046, + m_nu=[0.0, 0.0, 0.06], + Ob0=0.0486, ) diff --git a/autogalaxy/cosmology/wrap.py b/autogalaxy/cosmology/wrap.py deleted file mode 100644 index 9adbf6bd9..000000000 --- a/autogalaxy/cosmology/wrap.py +++ /dev/null @@ -1,17 +0,0 @@ -from astropy import cosmology as cosmo -from autogalaxy.cosmology.lensing import LensingCosmology - - -class Planck15(cosmo.FlatLambdaCDM, LensingCosmology): - def __init__(self): - Planck15_astropy = cosmo.Planck15 - - super().__init__( - H0=Planck15_astropy.H0, - Om0=Planck15_astropy.Om0, - Tcmb0=Planck15_astropy.Tcmb0, - Neff=Planck15_astropy.Neff, - m_nu=Planck15_astropy.m_nu, - Ob0=Planck15_astropy.Ob0, - name=Planck15_astropy.name, - ) diff --git a/autogalaxy/ellipse/plot/fit_ellipse_plot_util.py b/autogalaxy/ellipse/plot/fit_ellipse_plot_util.py index 7455a96d2..cea3c97ab 100644 --- a/autogalaxy/ellipse/plot/fit_ellipse_plot_util.py +++ b/autogalaxy/ellipse/plot/fit_ellipse_plot_util.py @@ -1,4 +1,3 @@ -from astropy import units import itertools import matplotlib.pyplot as plt import numpy as np @@ -6,6 +5,8 @@ def plot_ellipse_residuals(array, fit_list, colors, output, for_subplot: bool = False): + from astropy import units + color = itertools.cycle(colors) if for_subplot: diff --git a/autogalaxy/fixtures.py b/autogalaxy/fixtures.py index 569c8a805..510758a74 100644 --- a/autogalaxy/fixtures.py +++ b/autogalaxy/fixtures.py @@ -140,13 +140,6 @@ def make_galaxies_x2_inversion_7x7(): return [make_gal_x1_lp(), source_gal_inversion] -# COSMOLOGY # - - -def make_Planck15(): - return ag.cosmo.Planck15() - - # ELLIPSE FITING diff --git a/autogalaxy/imaging/model/analysis.py b/autogalaxy/imaging/model/analysis.py index 83f8b641f..2d1e6fabd 100644 --- a/autogalaxy/imaging/model/analysis.py +++ b/autogalaxy/imaging/model/analysis.py @@ -6,7 +6,7 @@ from autogalaxy.analysis.adapt_images.adapt_images import AdaptImages from autogalaxy.analysis.analysis.dataset import AnalysisDataset -from autogalaxy.cosmology.lensing import LensingCosmology +from autogalaxy.cosmology.model import LensingCosmology from autogalaxy.imaging.model.result import ResultImaging from autogalaxy.imaging.model.visualizer import VisualizerImaging from autogalaxy.imaging.fit_imaging import FitImaging diff --git a/autogalaxy/interferometer/model/analysis.py b/autogalaxy/interferometer/model/analysis.py index ac4a56c41..010ffae83 100644 --- a/autogalaxy/interferometer/model/analysis.py +++ b/autogalaxy/interferometer/model/analysis.py @@ -9,7 +9,7 @@ from autogalaxy.analysis.adapt_images.adapt_images import AdaptImages from autogalaxy.analysis.analysis.dataset import AnalysisDataset -from autogalaxy.cosmology.lensing import LensingCosmology +from autogalaxy.cosmology.model import LensingCosmology from autogalaxy.interferometer.model.result import ResultInterferometer from autogalaxy.interferometer.fit_interferometer import FitInterferometer from autogalaxy.interferometer.model.visualizer import VisualizerInterferometer diff --git a/autogalaxy/profiles/mass/dark/abstract.py b/autogalaxy/profiles/mass/dark/abstract.py index cc85de723..9af7bf795 100644 --- a/autogalaxy/profiles/mass/dark/abstract.py +++ b/autogalaxy/profiles/mass/dark/abstract.py @@ -4,7 +4,7 @@ import autoarray as aa from autogalaxy.profiles.mass.abstract.abstract import MassProfile -from autogalaxy.cosmology.lensing import LensingCosmology +from autogalaxy.cosmology.model import LensingCosmology from autogalaxy.profiles.mass.abstract.mge_numpy import ( MassProfileMGE, ) @@ -213,7 +213,7 @@ def rho_at_scale_radius_solar_mass_per_kpc3( The Cosmic average density is defined at the redshift of the profile. """ - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 cosmology = cosmology or Planck15() @@ -237,7 +237,7 @@ def delta_concentration( cosmology: LensingCosmology = None, ): - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 cosmology = cosmology or Planck15() @@ -274,7 +274,7 @@ def concentration( xp=np, ): - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 cosmology = cosmology or Planck15() @@ -321,7 +321,7 @@ def radius_at_200( """ Returns `r_{200m}` for this halo in **arcseconds** """ - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 cosmology = cosmology or Planck15() @@ -343,7 +343,7 @@ def mass_at_200_solar_masses( cosmology: LensingCosmology = None, xp=np, ): - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 cosmology = cosmology or Planck15() diff --git a/autogalaxy/profiles/mass/dark/cnfw.py b/autogalaxy/profiles/mass/dark/cnfw.py index c98ad451b..5ae5734a4 100644 --- a/autogalaxy/profiles/mass/dark/cnfw.py +++ b/autogalaxy/profiles/mass/dark/cnfw.py @@ -6,6 +6,7 @@ import autoarray as aa + class cNFWSph(AbstractgNFW): def __init__( self, @@ -15,30 +16,27 @@ def __init__( core_radius: float = 0.01, ): """ - Represents a spherical cored NFW density distribution - - Parameters - ---------- - centre - The (y,x) arc-second coordinates of the profile centre. - kappa_s - The overall normalization of the dark matter halo \| - (kappa_s = (rho_0 * D_d * scale_radius)/lensing_critical_density) - scale_radius - The cored NFW scale radius `theta_s`, as an angle on the sky in arcseconds. - core_radius - The cored NFW core radius `theta_c`, as an angle on the sky in arcseconds. - """ - - super().__init__( - centre=centre, - ell_comps=(0.0, 0.0)) + Represents a spherical cored NFW density distribution + + Parameters + ---------- + centre + The (y,x) arc-second coordinates of the profile centre. + kappa_s + The overall normalization of the dark matter halo \| + (kappa_s = (rho_0 * D_d * scale_radius)/lensing_critical_density) + scale_radius + The cored NFW scale radius `theta_s`, as an angle on the sky in arcseconds. + core_radius + The cored NFW core radius `theta_c`, as an angle on the sky in arcseconds. + """ + + super().__init__(centre=centre, ell_comps=(0.0, 0.0)) self.kappa_s = kappa_s self.scale_radius = scale_radius self.core_radius = core_radius - @aa.grid_dec.to_vector_yx @aa.grid_dec.transform def deflections_yx_2d_from(self, grid: aa.type.Grid2DLike, xp=np, **kwargs): @@ -62,21 +60,19 @@ def deflections_yx_2d_from(self, grid: aa.type.Grid2DLike, xp=np, **kwargs): theta = self.radial_grid_from(grid=grid, xp=xp, **kwargs).array theta = xp.maximum(theta, 1e-8) - factor = ( - 4.0 - * self.kappa_s - * self.scale_radius**2 - ) + factor = 4.0 * self.kappa_s * self.scale_radius**2 deflection_r = ( factor - * (self.F_func(theta, self.scale_radius, xp=xp) - self.F_func(theta, self.core_radius, xp=xp) - - (self.scale_radius - self.core_radius) * self.dev_F_func(theta, self.scale_radius, xp=xp) + * ( + self.F_func(theta, self.scale_radius, xp=xp) + - self.F_func(theta, self.core_radius, xp=xp) + - (self.scale_radius - self.core_radius) + * self.dev_F_func(theta, self.scale_radius, xp=xp) ) - / (theta * (self.scale_radius - self.core_radius)**2) + / (theta * (self.scale_radius - self.core_radius) ** 2) ) - return self._cartesian_grid_via_radial_from( grid=grid, radius=deflection_r, @@ -97,9 +93,9 @@ def F_func(self, theta, radius, xp=np): F = xp.where( mask1, ( - radius / 2 * xp.log(2 * radius / theta) - - xp.sqrt(radius ** 2 - theta ** 2) - * xp.arctanh(xp.sqrt((radius - theta) / (radius + theta))) + radius / 2 * xp.log(2 * radius / theta) + - xp.sqrt(radius**2 - theta**2) + * xp.arctanh(xp.sqrt((radius - theta) / (radius + theta))) ), F, ) @@ -107,9 +103,9 @@ def F_func(self, theta, radius, xp=np): F = xp.where( mask2, ( - radius / 2 * xp.log(2 * radius / theta) - + xp.sqrt(theta ** 2 - radius ** 2) - * xp.arctan(xp.sqrt((theta - radius) / (theta + radius))) + radius / 2 * xp.log(2 * radius / theta) + + xp.sqrt(theta**2 - radius**2) + * xp.arctan(xp.sqrt((theta - radius) / (theta + radius))) ), F, ) @@ -127,9 +123,10 @@ def dev_F_func(self, theta, radius, xp=np): dev_F = xp.where( mask1, ( - radius * xp.log(2 * radius / theta) - - (2 * radius ** 2 - theta ** 2) / xp.sqrt(radius ** 2 - theta ** 2) - * xp.arctanh(xp.sqrt((radius - theta) / (radius + theta))) + radius * xp.log(2 * radius / theta) + - (2 * radius**2 - theta**2) + / xp.sqrt(radius**2 - theta**2) + * xp.arctanh(xp.sqrt((radius - theta) / (radius + theta))) ), dev_F, ) @@ -143,9 +140,10 @@ def dev_F_func(self, theta, radius, xp=np): dev_F = xp.where( mask3, ( - radius * xp.log(2 * radius / theta) - + (theta ** 2 - 2 * radius ** 2) / xp.sqrt(theta ** 2 - radius ** 2) - * xp.arctan(xp.sqrt((theta - radius) / (theta + radius))) + radius * xp.log(2 * radius / theta) + + (theta**2 - 2 * radius**2) + / xp.sqrt(theta**2 - radius**2) + * xp.arctan(xp.sqrt((theta - radius) / (theta + radius))) ), dev_F, ) @@ -172,4 +170,4 @@ def potential_2d_from(self, grid: aa.type.Grid2DLike, xp=np, **kwargs): raise NotImplementedError( "potential_2d_from is not implemented for cNFWSph; a physical cNFW " "potential expression must be added before use." - ) \ No newline at end of file + ) diff --git a/autogalaxy/profiles/mass/dark/cnfw_mcr.py b/autogalaxy/profiles/mass/dark/cnfw_mcr.py index 1a22e1056..daffc42c9 100644 --- a/autogalaxy/profiles/mass/dark/cnfw_mcr.py +++ b/autogalaxy/profiles/mass/dark/cnfw_mcr.py @@ -4,12 +4,13 @@ from autogalaxy.profiles.mass.dark import mcr_util + class cNFWMCRLudlowSph(cNFWSph): def __init__( self, centre: Tuple[float, float] = (0.0, 0.0), mass_at_200: float = 1e9, - f_c = 0.01, + f_c=0.01, redshift_object: float = 0.5, redshift_source: float = 1.0, ): @@ -31,4 +32,9 @@ def __init__( redshift_source=redshift_source, ) - super().__init__(centre=centre, kappa_s=kappa_s, scale_radius=scale_radius, core_radius=core_radius) \ No newline at end of file + super().__init__( + centre=centre, + kappa_s=kappa_s, + scale_radius=scale_radius, + core_radius=core_radius, + ) diff --git a/autogalaxy/profiles/mass/dark/gnfw_virial_mass_conc.py b/autogalaxy/profiles/mass/dark/gnfw_virial_mass_conc.py index 7a2292fbd..cae42f239 100644 --- a/autogalaxy/profiles/mass/dark/gnfw_virial_mass_conc.py +++ b/autogalaxy/profiles/mass/dark/gnfw_virial_mass_conc.py @@ -9,51 +9,53 @@ def kappa_s_and_scale_radius( cosmology, virial_mass, c_2, overdens, redshift_object, redshift_source, inner_slope ): - from astropy import units from scipy.integrate import quad - concentration = (2 - inner_slope) * c_2 # gNFW concentration + concentration = (2.0 - inner_slope) * c_2 # gNFW concentration - critical_density = ( - cosmology.critical_density(redshift_object).to(units.solMass / units.kpc**3) - ).value + critical_density = cosmology.critical_density( + redshift_object, xp=np + ) # Msun / kpc^3 critical_surface_density = ( cosmology.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( - redshift_0=redshift_object, redshift_1=redshift_source + redshift_0=redshift_object, + redshift_1=redshift_source, + xp=np, ) - ) + ) # Msun / kpc^2 - kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=redshift_object) + kpc_per_arcsec = cosmology.kpc_per_arcsec_from( + redshift=redshift_object, xp=np + ) # kpc / arcsec if overdens == 0: - x = cosmology.Om(redshift_object) - 1 - overdens = 18 * np.pi**2 + 82 * x - 39 * x**2 # Bryan & Norman (1998) + x = cosmology.Om(redshift_object, xp=np) - 1.0 + overdens = 18.0 * np.pi**2 + 82.0 * x - 39.0 * x**2 # Bryan & Norman (1998) + # r_vir in kpc virial_radius = ( virial_mass / (overdens * critical_density * (4.0 * np.pi / 3.0)) - ) ** ( - 1.0 / 3.0 - ) # r_vir + ) ** (1.0 / 3.0) - scale_radius_kpc = ( - virial_radius / concentration - ) # scale radius of gNFW profile in kpc + # scale radius in kpc + scale_radius_kpc = virial_radius / concentration - ############################## + # Normalization integral for gNFW def integrand(r): - return (r**2 / r**inner_slope) * (1 + r / scale_radius_kpc) ** (inner_slope - 3) + return (r**2 / r**inner_slope) * (1.0 + r / scale_radius_kpc) ** ( + inner_slope - 3.0 + ) de_c = ( (overdens / 3.0) * (virial_radius**3 / scale_radius_kpc**inner_slope) - / quad(integrand, 0, virial_radius)[0] - ) # rho_c - ############################## + / quad(integrand, 0.0, virial_radius)[0] + ) - rho_s = critical_density * de_c # rho_s - kappa_s = rho_s * scale_radius_kpc / critical_surface_density # kappa_s - scale_radius = scale_radius_kpc / kpc_per_arcsec # scale radius in arcsec + rho_s = critical_density * de_c # Msun / kpc^3 + kappa_s = rho_s * scale_radius_kpc / critical_surface_density # dimensionless + scale_radius = scale_radius_kpc / kpc_per_arcsec # arcsec return kappa_s, scale_radius, virial_radius, overdens diff --git a/autogalaxy/profiles/mass/dark/gnfw_virial_mass_gnfw_conc.py b/autogalaxy/profiles/mass/dark/gnfw_virial_mass_gnfw_conc.py index e30205982..c07d290b3 100644 --- a/autogalaxy/profiles/mass/dark/gnfw_virial_mass_gnfw_conc.py +++ b/autogalaxy/profiles/mass/dark/gnfw_virial_mass_gnfw_conc.py @@ -15,51 +15,51 @@ def kappa_s_and_scale_radius( redshift_source, inner_slope, ): - from astropy import units from scipy.integrate import quad - # gNFW concentration imported - - critical_density = ( - cosmology.critical_density(redshift_object).to(units.solMass / units.kpc**3) - ).value + # Msun / kpc^3 (no astropy.units) + critical_density = cosmology.critical_density(redshift_object, xp=np) + # Msun / kpc^2 critical_surface_density = ( cosmology.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( - redshift_0=redshift_object, redshift_1=redshift_source + redshift_0=redshift_object, + redshift_1=redshift_source, + xp=np, ) ) - kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=redshift_object) + # kpc / arcsec + kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=redshift_object, xp=np) if overdens == 0: - x = cosmology.Om(redshift_object) - 1 - overdens = 18 * np.pi**2 + 82 * x - 39 * x**2 # Bryan & Norman (1998) + x = cosmology.Om(redshift_object, xp=np) - 1.0 + overdens = 18.0 * np.pi**2 + 82.0 * x - 39.0 * x**2 # Bryan & Norman (1998) + # r_vir in kpc virial_radius = ( virial_mass / (overdens * critical_density * (4.0 * np.pi / 3.0)) - ) ** ( - 1.0 / 3.0 - ) # r_vir + ) ** (1.0 / 3.0) - scale_radius_kpc = ( - virial_radius / concentration - ) # scale radius of gNFW profile in kpc + # scale radius of gNFW in kpc + scale_radius_kpc = virial_radius / concentration ############################## def integrand(r): - return (r**2 / r**inner_slope) * (1 + r / scale_radius_kpc) ** (inner_slope - 3) + return (r**2 / r**inner_slope) * (1.0 + r / scale_radius_kpc) ** ( + inner_slope - 3.0 + ) de_c = ( (overdens / 3.0) * (virial_radius**3 / scale_radius_kpc**inner_slope) - / quad(integrand, 0, virial_radius)[0] - ) # rho_c + / quad(integrand, 0.0, virial_radius)[0] + ) ############################## - rho_s = critical_density * de_c # rho_s - kappa_s = rho_s * scale_radius_kpc / critical_surface_density # kappa_s - scale_radius = scale_radius_kpc / kpc_per_arcsec # scale radius in arcsec + rho_s = critical_density * de_c # Msun / kpc^3 + kappa_s = rho_s * scale_radius_kpc / critical_surface_density # dimensionless + scale_radius = scale_radius_kpc / kpc_per_arcsec # arcsec return kappa_s, scale_radius, virial_radius, overdens diff --git a/autogalaxy/profiles/mass/dark/mcr_util.py b/autogalaxy/profiles/mass/dark/mcr_util.py index 62824e4d7..2ba54bcb7 100644 --- a/autogalaxy/profiles/mass/dark/mcr_util.py +++ b/autogalaxy/profiles/mass/dark/mcr_util.py @@ -9,36 +9,34 @@ def kappa_s_and_scale_radius_for_duffy(mass_at_200, redshift_object, redshift_so Interprets mass as *`M_{200c}`*, not `M_{200m}`. """ - - from astropy import units - - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 cosmology = Planck15() - cosmic_average_density = ( - cosmology.critical_density(redshift_object).to(units.solMass / units.kpc**3) - ).value + # Msun / kpc^3 (no units conversion needed) + cosmic_average_density = cosmology.critical_density(redshift_object, xp=np) + # Msun / kpc^2 critical_surface_density = ( cosmology.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( - redshift_0=redshift_object, redshift_1=redshift_source + redshift_0=redshift_object, + redshift_1=redshift_source, + xp=np, ) ) - kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=redshift_object) + # kpc / arcsec + kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=redshift_object, xp=np) + # r200 in kpc radius_at_200 = ( mass_at_200 / (200.0 * cosmic_average_density * (4.0 * np.pi / 3.0)) - ) ** ( - 1.0 / 3.0 - ) # r200 - coefficient = 5.71 * (1.0 + redshift_object) ** ( - -0.47 - ) # The coefficient of Duffy mass-concentration (Duffy+2008) - concentration = coefficient * (mass_at_200 / 2.952465309e12) ** ( - -0.084 - ) # mass-concentration relation. (Duffy+2008) + ) ** (1.0 / 3.0) + + # Duffy+2008 mass–concentration (as in your code) + coefficient = 5.71 * (1.0 + redshift_object) ** (-0.47) + concentration = coefficient * (mass_at_200 / 2.952465309e12) ** (-0.084) + de_c = ( 200.0 / 3.0 @@ -46,12 +44,12 @@ def kappa_s_and_scale_radius_for_duffy(mass_at_200, redshift_object, redshift_so concentration**3 / (np.log(1.0 + concentration) - concentration / (1.0 + concentration)) ) - ) # rho_c + ) - scale_radius_kpc = radius_at_200 / concentration # scale radius in kpc - rho_s = cosmic_average_density * de_c # rho_s - kappa_s = rho_s * scale_radius_kpc / critical_surface_density # kappa_s - scale_radius = scale_radius_kpc / kpc_per_arcsec # scale radius in arcsec + scale_radius_kpc = radius_at_200 / concentration + rho_s = cosmic_average_density * de_c # Msun / kpc^3 + kappa_s = rho_s * scale_radius_kpc / critical_surface_density # dimensionless + scale_radius = scale_radius_kpc / kpc_per_arcsec # arcsec return kappa_s, scale_radius, radius_at_200 @@ -67,10 +65,9 @@ def _ludlow16_cosmology_callback( """ import numpy as np - from astropy import units from colossus.cosmology import cosmology as col_cosmology from colossus.halo.concentration import concentration as col_concentration - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 # ----------------------- # Colossus cosmology @@ -86,24 +83,24 @@ def _ludlow16_cosmology_callback( ) # ----------------------- - # Astropy cosmology + # AutoGalaxy cosmology (no astropy.units) # ----------------------- cosmology = Planck15() - cosmic_average_density = ( - cosmology.critical_density(redshift_object) - .to(units.solMass / units.kpc**3) - .value - ) + # Msun / kpc^3 (your xp drop-in should return this directly) + cosmic_average_density = cosmology.critical_density(redshift_object, xp=np) + # Msun / kpc^2 critical_surface_density = ( cosmology.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( redshift_0=redshift_object, redshift_1=redshift_source, + xp=np, ) ) - kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=redshift_object) + # kpc / arcsec + kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=redshift_object, xp=np) return ( np.float64(concentration), @@ -204,7 +201,10 @@ def kappa_s_and_scale_radius_for_ludlow( return kappa_s, scale_radius, radius_at_200 -def kappa_s_scale_radius_and_core_radius_for_ludlow(mass_at_200, scatter_sigma, f_c, redshift_object, redshift_source): + +def kappa_s_scale_radius_and_core_radius_for_ludlow( + mass_at_200, scatter_sigma, f_c, redshift_object, redshift_source +): """ Computes the AutoGalaxy cNFW parameters (kappa_s, scale_radius, core_radius) for a cored NFW halo of the given mass, enforcing the Penarrubia '12 mass-concentration relation. @@ -258,13 +258,17 @@ def kappa_s_scale_radius_and_core_radius_for_ludlow(mass_at_200, scatter_sigma, 1.0 / 3.0 ) # r200 - mcr_penarrubia = ((f_c**2 * xp.log(1 + concentration / f_c) + (1 - 2 * f_c) * xp.log(1 + concentration)) / (1 + f_c)**2 - - concentration / ((1+concentration) * (1-f_c))) #mass concentration relation (Penarrubia+2012) + mcr_penarrubia = ( + f_c**2 * xp.log(1 + concentration / f_c) + + (1 - 2 * f_c) * xp.log(1 + concentration) + ) / (1 + f_c) ** 2 - concentration / ( + (1 + concentration) * (1 - f_c) + ) # mass concentration relation (Penarrubia+2012) scale_radius_kpc = radius_at_200 / concentration # scale radius in kpc rho_0 = mass_at_200 / (4 * xp.pi * scale_radius_kpc**3 * mcr_penarrubia) kappa_s = rho_0 * scale_radius_kpc / critical_surface_density # kappa_s scale_radius = scale_radius_kpc / kpc_per_arcsec # scale radius in arcsec - core_radius = f_c * scale_radius # core radius in arcsec + core_radius = f_c * scale_radius # core radius in arcsec return kappa_s, scale_radius, core_radius, radius_at_200 diff --git a/autogalaxy/profiles/mass/dark/nfw_truncated.py b/autogalaxy/profiles/mass/dark/nfw_truncated.py index 7a1ff50fb..6894f3f43 100644 --- a/autogalaxy/profiles/mass/dark/nfw_truncated.py +++ b/autogalaxy/profiles/mass/dark/nfw_truncated.py @@ -3,7 +3,7 @@ import autoarray as aa -from autogalaxy.cosmology.lensing import LensingCosmology +from autogalaxy.cosmology.model import LensingCosmology from autogalaxy.profiles.mass.dark.abstract import AbstractgNFW @@ -114,7 +114,7 @@ def mass_at_truncation_radius_solar_mass( cosmology: LensingCosmology = None, xp=np, ): - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 cosmology = cosmology or Planck15() diff --git a/autogalaxy/profiles/mass/dark/nfw_virial_mass_conc.py b/autogalaxy/profiles/mass/dark/nfw_virial_mass_conc.py index d11cf8acd..2fc1bf511 100644 --- a/autogalaxy/profiles/mass/dark/nfw_virial_mass_conc.py +++ b/autogalaxy/profiles/mass/dark/nfw_virial_mass_conc.py @@ -1,36 +1,56 @@ from typing import Tuple +import numpy as np -from autogalaxy.profiles.mass.dark.nfw import NFWSph -import numpy as np +from autogalaxy.profiles.mass.dark.nfw import NFWSph +from autogalaxy.cosmology.model import Planck15 def kappa_s_and_scale_radius( - virial_mass, concentration, virial_overdens, redshift_object, redshift_source + virial_mass, + concentration, + virial_overdens, + redshift_object, + redshift_source, ): + """ + Computes kappa_s and scale radius for an NFW halo given virial mass and concentration. + + No astropy.units required. - from astropy import units - from autogalaxy.cosmology.wrap import Planck15 + Assumes: + - virial_mass in Msun + - critical_density in Msun / kpc^3 + - critical_surface_density in Msun / kpc^2 + - kpc_per_arcsec in kpc / arcsec + """ cosmology = Planck15() - cosmic_average_density = ( - cosmology.critical_density(redshift_object).to(units.solMass / units.kpc**3) - ).value + # Msun / kpc^3 + cosmic_average_density = cosmology.critical_density(redshift_object, xp=np) + # Msun / kpc^2 critical_surface_density = ( cosmology.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( - redshift_0=redshift_object, redshift_1=redshift_source + redshift_0=redshift_object, + redshift_1=redshift_source, + xp=np, ) ) - kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=redshift_object) + # kpc / arcsec + kpc_per_arcsec = cosmology.kpc_per_arcsec_from( + redshift=redshift_object, + xp=np, + ) + # Virial radius r_vir in kpc virial_radius = ( virial_mass / (virial_overdens * cosmic_average_density * (4.0 * np.pi / 3.0)) - ) ** ( - 1.0 / 3.0 - ) # r_vir + ) ** (1.0 / 3.0) + + # Characteristic overdensity factor de_c = ( virial_overdens / 3.0 @@ -38,12 +58,19 @@ def kappa_s_and_scale_radius( concentration**3 / (np.log(1.0 + concentration) - concentration / (1.0 + concentration)) ) - ) # rho_c + ) + + # Scale radius in kpc + scale_radius_kpc = virial_radius / concentration + + # Characteristic density rho_s in Msun / kpc^3 + rho_s = cosmic_average_density * de_c + + # Dimensionless lensing normalization + kappa_s = rho_s * scale_radius_kpc / critical_surface_density - scale_radius_kpc = virial_radius / concentration # scale radius in kpc - rho_s = cosmic_average_density * de_c # rho_s - kappa_s = rho_s * scale_radius_kpc / critical_surface_density # kappa_s - scale_radius = scale_radius_kpc / kpc_per_arcsec # scale radius in arcsec + # Scale radius in arcsec + scale_radius = scale_radius_kpc / kpc_per_arcsec return kappa_s, scale_radius, virial_radius diff --git a/autogalaxy/profiles/mass/point/smbh.py b/autogalaxy/profiles/mass/point/smbh.py index 40fc054ec..9fde58255 100644 --- a/autogalaxy/profiles/mass/point/smbh.py +++ b/autogalaxy/profiles/mass/point/smbh.py @@ -29,7 +29,7 @@ def __init__( redshift_source The redshift of the source galaxy, which is used to convert the mass of the SMBH to an Einstein radius. """ - from autogalaxy.cosmology.wrap import Planck15 + from autogalaxy.cosmology.model import Planck15 cosmology = Planck15() diff --git a/autogalaxy/profiles/mass/stellar/gaussian.py b/autogalaxy/profiles/mass/stellar/gaussian.py index 2a8778d7b..aab1a82b9 100644 --- a/autogalaxy/profiles/mass/stellar/gaussian.py +++ b/autogalaxy/profiles/mass/stellar/gaussian.py @@ -39,7 +39,6 @@ def __init__( self.intensity = intensity self.sigma = sigma - def deflections_yx_2d_from(self, grid: aa.type.Grid2DLike, xp=np, **kwargs): """ Calculate the deflection angles at a given set of arc-second gridded coordinates. @@ -191,7 +190,7 @@ def axis_ratio(self, xp=np): def zeta_from(self, grid: aa.type.Grid2DLike, xp=np): q = self.axis_ratio(xp) - q2 = q ** 2.0 + q2 = q**2.0 ind_pos_y = grid.array[:, 0] >=0 shape_grid = np.shape(grid) @@ -251,8 +250,9 @@ def wofz(self, z, xp=np): # --- Region 5: special small-imaginary case --- U5 = xp.array([1.320522, 35.7668, 219.031, 1540.787, 3321.990, 36183.31]) - V5 = xp.array([1.841439, 61.57037, 364.2191, 2186.181, - 9022.228, 24322.84, 32066.6]) + V5 = xp.array( + [1.841439, 61.57037, 364.2191, 2186.181, 9022.228, 24322.84, 32066.6] + ) t = 1 / sqrt_pi for u in U5: @@ -265,10 +265,18 @@ def wofz(self, z, xp=np): w5 = xp.exp(-z2) + 1j * z * t / s # --- Region 6: remaining small-|z| region --- - U6 = xp.array([5.9126262, 30.180142, 93.15558, - 181.92853, 214.38239, 122.60793]) - V6 = xp.array([10.479857, 53.992907, 170.35400, - 348.70392, 457.33448, 352.73063, 122.60793]) + U6 = xp.array([5.9126262, 30.180142, 93.15558, 181.92853, 214.38239, 122.60793]) + V6 = xp.array( + [ + 10.479857, + 53.992907, + 170.35400, + 348.70392, + 457.33448, + 352.73063, + 122.60793, + ] + ) t = 1 / sqrt_pi for u in U6: @@ -282,7 +290,9 @@ def wofz(self, z, xp=np): # --- Regions --- reg1 = (r2 >= 62.0) | ((r2 >= 30.0) & (r2 < 62.0) & (y2 >= 1e-13)) - reg2 = ((r2 >= 30) & (r2 < 62) & (y2 < 1e-13)) | ((r2 >= 2.5) & (r2 < 30) & (y2 < 0.072)) + reg2 = ((r2 >= 30) & (r2 < 62) & (y2 < 1e-13)) | ( + (r2 >= 2.5) & (r2 < 30) & (y2 < 0.072) + ) # --- Combine regions using pure array logic --- w = w6 diff --git a/autogalaxy/profiles/mass/total/power_law_multipole.py b/autogalaxy/profiles/mass/total/power_law_multipole.py index c0f652af3..63a4f4653 100644 --- a/autogalaxy/profiles/mass/total/power_law_multipole.py +++ b/autogalaxy/profiles/mass/total/power_law_multipole.py @@ -147,12 +147,10 @@ def k_m_and_angle_m_from(self, xp=np) -> Tuple[float, float]: angle_m The multipole orientation angle in radians. """ - from astropy import units - k_m, angle_m = convert.multipole_k_m_and_phi_m_from( multipole_comps=self.multipole_comps, m=self.m, xp=xp ) - angle_m *= units.deg.to(units.rad) + angle_m *= xp.asarray(np.pi / 180.0) return k_m, angle_m diff --git a/autogalaxy/quantity/model/analysis.py b/autogalaxy/quantity/model/analysis.py index 3537710f7..1889199b2 100644 --- a/autogalaxy/quantity/model/analysis.py +++ b/autogalaxy/quantity/model/analysis.py @@ -5,7 +5,7 @@ import autofit as af from autogalaxy.analysis.analysis.analysis import Analysis -from autogalaxy.cosmology.lensing import LensingCosmology +from autogalaxy.cosmology.model import LensingCosmology from autogalaxy.quantity.dataset_quantity import DatasetQuantity from autogalaxy.quantity.model.result import ResultQuantity from autogalaxy.quantity.model.visualizer import VisualizerQuantity diff --git a/autogalaxy/util/mock/mock_cosmology.py b/autogalaxy/util/mock/mock_cosmology.py index d41f918fb..17fee4abd 100644 --- a/autogalaxy/util/mock/mock_cosmology.py +++ b/autogalaxy/util/mock/mock_cosmology.py @@ -1,4 +1,5 @@ import math +import numpy as np # Mock Cosmology # @@ -34,13 +35,28 @@ def kpc_per_arcsec_proper(self, z): def angular_diameter_distance(self, z): return Value(value=1.0) - def angular_diameter_distance_z1z2(self, z1, z2): - from astropy import constants + def angular_diameter_distance_z1z2(self, z1, z2, xp=np): + """ + Replacement for the astropy-constants version. - const = constants.c.to("kpc / s") ** 2.0 / ( - 4 * math.pi * constants.G.to("kpc3 / (solMass s2)") - ) - return Value(value=self.critical_surface_density * const.value) + Computes the factor: + + const = c^2 / (4*pi*G) + + in units of Msun / kpc. + + No astropy.constants required. + """ + + # Speed of light in kpc/s + c_kpc_s = xp.asarray(299792.458) / xp.asarray(3.085677581e16) + + # Gravitational constant in kpc^3 / (Msun s^2) + G_kpc3_Msun_s2 = xp.asarray(4.30091e-6) / xp.asarray((3.085677581e16) ** 2) + + const = (c_kpc_s**2) / (xp.asarray(4.0) * xp.pi * G_kpc3_Msun_s2) + + return Value(value=self.critical_surface_density * const) def critical_density(self, z): return Value(value=self.cosmic_average_density) diff --git a/test_autogalaxy/conftest.py b/test_autogalaxy/conftest.py index a017b64e7..9c8027d9c 100644 --- a/test_autogalaxy/conftest.py +++ b/test_autogalaxy/conftest.py @@ -302,11 +302,6 @@ def make_galaxies_x2_7x7(): return fixtures.make_galaxies_x2_7x7() -@pytest.fixture(name="Planck15") -def make_Planck15(): - return fixtures.make_Planck15() - - @pytest.fixture(name="adapt_galaxy_name_image_dict_7x7") def make_adapt_galaxy_name_image_dict_7x7(): return fixtures.make_adapt_galaxy_name_image_dict_7x7() diff --git a/test_autogalaxy/cosmology/test_lensing.py b/test_autogalaxy/cosmology/test_lensing.py deleted file mode 100644 index 057204932..000000000 --- a/test_autogalaxy/cosmology/test_lensing.py +++ /dev/null @@ -1,80 +0,0 @@ -import pytest -import numpy as np - - -def test__arcsec_to_kpc_conversion(Planck15): - arcsec_per_kpc = Planck15.arcsec_per_kpc_from(redshift=0.1) - - assert arcsec_per_kpc == pytest.approx(0.525060, 1e-5) - - kpc_per_arcsec = Planck15.kpc_per_arcsec_from(redshift=0.1) - - assert kpc_per_arcsec == pytest.approx(1.904544, 1e-5) - - arcsec_per_kpc = Planck15.arcsec_per_kpc_from(redshift=1.0) - - assert arcsec_per_kpc == pytest.approx(0.1214785, 1e-5) - - kpc_per_arcsec = Planck15.kpc_per_arcsec_from(redshift=1.0) - - assert kpc_per_arcsec == pytest.approx(8.231907, 1e-5) - - -def test__angular_diameter_distances(Planck15): - angular_diameter_distance_to_earth_kpc = ( - Planck15.angular_diameter_distance_to_earth_in_kpc_from(redshift=0.1) - ) - - assert angular_diameter_distance_to_earth_kpc == pytest.approx(392840, 1e-5) - - angular_diameter_distance_between_redshifts_kpc = ( - Planck15.angular_diameter_distance_between_redshifts_in_kpc_from( - redshift_0=0.1, redshift_1=1.0 - ) - ) - - assert angular_diameter_distance_between_redshifts_kpc == pytest.approx( - 1481890.4, 1e-5 - ) - - -def test__cosmic_average_densities_solar_mass_per_kpc3(Planck15): - cosmic_average_density = Planck15.cosmic_average_density_from(redshift=0.6) - - assert cosmic_average_density == pytest.approx(81280.09116133313, 1.0e-4) - - cosmic_average_density = Planck15.cosmic_average_density_solar_mass_per_kpc3_from( - redshift=0.6 - ) - - assert cosmic_average_density == pytest.approx(249.20874, 1.0e-4) - - -def test__critical_surface_mass_densities(Planck15): - critical_surface_density = Planck15.critical_surface_density_between_redshifts_from( - redshift_0=0.1, redshift_1=1.0 - ) - - assert critical_surface_density == pytest.approx(17593241668, 1e-2) - - critical_surface_density = ( - Planck15.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( - redshift_0=0.1, redshift_1=1.0 - ) - ) - - assert critical_surface_density == pytest.approx(4.85e9, 1e-2) - - -def test__velocity_dispersion_from(Planck15): - velocity_dispersion = Planck15.velocity_dispersion_from( - redshift_0=0.5, redshift_1=1.0, einstein_radius=1.0 - ) - - assert velocity_dispersion == pytest.approx(249.03449, 1.0e-4) - - velocity_dispersion = Planck15.velocity_dispersion_from( - redshift_0=0.5, redshift_1=1.0, einstein_radius=2.0 - ) - - assert velocity_dispersion == pytest.approx(np.sqrt(2) * 249.03449, 1.0e-4) diff --git a/test_autogalaxy/cosmology/test_model.py b/test_autogalaxy/cosmology/test_model.py index 8154a82da..2ced0faf6 100644 --- a/test_autogalaxy/cosmology/test_model.py +++ b/test_autogalaxy/cosmology/test_model.py @@ -1,11 +1,78 @@ import pytest +import numpy as np +import autogalaxy as ag -def test__cosmology(Planck15): - from autogalaxy.cosmology.model import FlatwCDMWrap +def test__arcsec_to_kpc_conversion(): - cosmology = FlatwCDMWrap() + cosmology = ag.cosmology.Planck15() + + arcsec_per_kpc = cosmology.arcsec_per_kpc_from(redshift=0.1) + + assert arcsec_per_kpc == pytest.approx(0.525060, 1e-5) + + kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=0.1) + + assert kpc_per_arcsec == pytest.approx(1.904544, 1e-5) + + arcsec_per_kpc = cosmology.arcsec_per_kpc_from(redshift=1.0) + + assert arcsec_per_kpc == pytest.approx(0.1214785, 5e-5) + + kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=1.0) + + assert kpc_per_arcsec == pytest.approx(8.231907, 5e-5) + + +def test__angular_diameter_distance_z1z2(): + + cosmology = ag.cosmology.FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=2.725) + + angular_diameter_distance = cosmology.angular_diameter_distance_kpc_z1z2(0.1, 1.0) + + assert angular_diameter_distance == pytest.approx(1442537.80833, 1.0e-4) + + +def test__angular_diameter_distances(): + + cosmology = ag.cosmology.Planck15() + + angular_diameter_distance_to_earth_kpc = ( + cosmology.angular_diameter_distance_to_earth_in_kpc_from(redshift=0.1) + ) + + assert angular_diameter_distance_to_earth_kpc == pytest.approx(392840, 1e-5) + + angular_diameter_distance_between_redshifts_kpc = ( + cosmology.angular_diameter_distance_between_redshifts_in_kpc_from( + redshift_0=0.1, redshift_1=1.0 + ) + ) + + assert angular_diameter_distance_between_redshifts_kpc == pytest.approx( + 1481890.4, 5e-5 + ) + + +def test__cosmic_average_densities_solar_mass_per_kpc3(): + + cosmology = ag.cosmology.Planck15() + + cosmic_average_density = cosmology.cosmic_average_density_from(redshift=0.6) + + assert cosmic_average_density == pytest.approx(81280.09116133313, 1.0e-4) + + cosmic_average_density = cosmology.cosmic_average_density_solar_mass_per_kpc3_from( + redshift=0.6 + ) + + assert cosmic_average_density == pytest.approx(249.20874, 1.0e-4) + + +def test__critical_surface_mass_densities(): + + cosmology = ag.cosmology.Planck15() critical_surface_density = ( cosmology.critical_surface_density_between_redshifts_from( @@ -13,11 +80,20 @@ def test__cosmology(Planck15): ) ) - assert critical_surface_density == pytest.approx(17613991217.945473, 1.0e-4) + assert critical_surface_density == pytest.approx(17593241668, 1e-2) - from autogalaxy.cosmology.model import FlatLambdaCDMWrap + critical_surface_density = ( + cosmology.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( + redshift_0=0.1, redshift_1=1.0 + ) + ) + + assert critical_surface_density == pytest.approx(4.85e9, 1e-2) - cosmology = FlatLambdaCDMWrap() + +def test__critical_surface_density(): + + cosmology = ag.cosmology.FlatLambdaCDM() critical_surface_density = ( cosmology.critical_surface_density_between_redshifts_from( @@ -26,3 +102,31 @@ def test__cosmology(Planck15): ) assert critical_surface_density == pytest.approx(17613991217.945473, 1.0e-4) + + +def test__scaling_factor_between_redshifts_from(): + + cosmology = ag.cosmology.FlatLambdaCDM() + + scaling_factor = cosmology.scaling_factor_between_redshifts_from( + redshift_0=0.5, redshift_1=1.0, redshift_final=2.0 + ) + + assert scaling_factor == pytest.approx(0.6739452581456, 1e-4) + + +def test__velocity_dispersion_from(): + + cosmology = ag.cosmology.Planck15() + + velocity_dispersion = cosmology.velocity_dispersion_from( + redshift_0=0.5, redshift_1=1.0, einstein_radius=1.0 + ) + + assert velocity_dispersion == pytest.approx(284.935499691701, 1.0e-4) + + velocity_dispersion = cosmology.velocity_dispersion_from( + redshift_0=0.5, redshift_1=1.0, einstein_radius=2.0 + ) + + assert velocity_dispersion == pytest.approx(np.sqrt(2) * 284.935499691701, 1.0e-4) diff --git a/test_autogalaxy/imaging/test_simulator.py b/test_autogalaxy/imaging/test_simulator.py index 64a64707c..1b9aacd9e 100644 --- a/test_autogalaxy/imaging/test_simulator.py +++ b/test_autogalaxy/imaging/test_simulator.py @@ -1,4 +1,3 @@ -from astropy.io import fits import numpy as np import os from os import path @@ -9,6 +8,9 @@ def create_fits(fits_path, array): + + from astropy.io import fits + file_dir = os.path.split(fits_path)[0] if not os.path.exists(file_dir): @@ -61,6 +63,8 @@ def test__from_fits__all_imaging_data_structures_are_flipped_for_ds9(): overwrite=True, ) + from astropy.io import fits + hdu_list = fits.open(image_path) image = np.array(hdu_list[0].data).astype("float64") assert (image == np.array([[1.0, 0.0], [0.0, 0.0]])).all() diff --git a/test_autogalaxy/profiles/mass/dark/test_abstract.py b/test_autogalaxy/profiles/mass/dark/test_abstract.py index e3cfecc2f..a058381bc 100644 --- a/test_autogalaxy/profiles/mass/dark/test_abstract.py +++ b/test_autogalaxy/profiles/mass/dark/test_abstract.py @@ -253,24 +253,12 @@ def test__mass_at_200__unit_conversions_work(): ) assert mass_at_200 == pytest.approx(mass_calc, 1.0e-5) - # cosmology = ag.m.MockCosmology(arcsec_per_kpc=0.5, kpc_per_arcsec=2.0, critical_surface_density=2.0, - # cosmic_average_density=1.0) - # - # radius_at_200 = mp.radius_at_200_for_units(unit_length='arcsec', redshift_galaxy=0.5, redshift_source=1.0, - # cosmology=cosmology) - # - # mass_at_200 = mp.mass_at_200(cosmology=cosmology, redshift_galaxy=0.5, redshift_source=1.0, unit_length='arcsec', - # unit_mass='solMass') - # - # mass_calc = 200.0 * ((4.0 / 3.0) * np.pi) * cosmology.cosmic_average_density * (radius_at_200 ** 3.0) - # assert mass_at_200 == pytest.approx(mass_calc, 1.0e-5) - def test__values_of_quantities_for_real_cosmology(): - from autogalaxy.cosmology.model import LambdaCDMWrap + from autogalaxy.cosmology.model import FlatLambdaCDM - cosmology = LambdaCDMWrap(H0=70.0, Om0=0.3, Ode0=0.7) + cosmology = FlatLambdaCDM(H0=70.0, Om0=0.3, m_nu=0.06) mp = ag.mp.NFWTruncatedSph(kappa_s=0.5, scale_radius=5.0, truncation_radius=10.0) @@ -313,12 +301,12 @@ def test__values_of_quantities_for_real_cosmology(): cosmology=cosmology, ) - assert rho == pytest.approx(29086405.474155396, 1.0e-4) - assert delta_concentration == pytest.approx(213881.71990418772, 1.0e-4) - assert concentration == pytest.approx(18.67527773217461, 1.0e-4) - assert radius_at_200 == pytest.approx(93.37638866087305, 1.0e-4) - assert mass_at_200 == pytest.approx(27641476612470.0, 1.0e-4) - assert mass_at_truncation_radius == pytest.approx(14871675423873.854, 1.0e-4) + assert rho == pytest.approx(29161077.6138, rel=1e-4) + assert delta_concentration == pytest.approx(214430.445767, 1.0e-4) + assert concentration == pytest.approx(18.694005966122, 1.0e-4) + assert radius_at_200 == pytest.approx(93.4700298306, 1.0e-4) + assert mass_at_200 == pytest.approx(27664107754813.824, 1.0e-4) + assert mass_at_truncation_radius == pytest.approx(14883851437772.34, 1.0e-4) rho = mp.rho_at_scale_radius_solar_mass_per_kpc3( redshift_object=0.6, redshift_source=2.5, cosmology=cosmology @@ -359,9 +347,9 @@ def test__values_of_quantities_for_real_cosmology(): cosmology=cosmology, ) - assert rho == pytest.approx(29086405.474155396, 1.0e-4) - assert delta_concentration == pytest.approx(110527.8022275522, 1.0e-4) - assert concentration == pytest.approx(14.394455391541, 1.0e-4) - assert radius_at_200 == pytest.approx(71.97227695770, 1.0e-4) - assert mass_at_200 == pytest.approx(24493332582335.38, 1.0e-4) - assert mass_at_truncation_radius == pytest.approx(13177910041504.6, 1.0e-4) + assert rho == pytest.approx(29161077.6138651, 1.0e-4) + assert delta_concentration == pytest.approx(110450.279912950, 1.0e-4) + assert concentration == pytest.approx(14.3904385787937, 1.0e-4) + assert radius_at_200 == pytest.approx(71.9521928939688, 1.0e-4) + assert mass_at_200 == pytest.approx(24499163428482.89, 1.0e-4) + assert mass_at_truncation_radius == pytest.approx(13181047155073.828, 1.0e-4) diff --git a/test_autogalaxy/profiles/mass/dark/test_cnfw.py b/test_autogalaxy/profiles/mass/dark/test_cnfw.py index 2dae506c8..1dca64900 100644 --- a/test_autogalaxy/profiles/mass/dark/test_cnfw.py +++ b/test_autogalaxy/profiles/mass/dark/test_cnfw.py @@ -3,10 +3,16 @@ import autogalaxy as ag + def test__deflections_yx_2d_from(): - cnfw = ag.mp.cNFWSph(centre=(0.0, 0.0), kappa_s=0.01591814312464436, scale_radius=0.36, core_radius=0.036) + cnfw = ag.mp.cNFWSph( + centre=(0.0, 0.0), + kappa_s=0.01591814312464436, + scale_radius=0.36, + core_radius=0.036, + ) deflection_2d = cnfw.deflections_yx_2d_from(grid=ag.Grid2DIrregular([[1.0, 0.0]])) - deflection_r = np.sqrt(deflection_2d[0, 0]**2 + deflection_2d[0, 1]**2) + deflection_r = np.sqrt(deflection_2d[0, 0] ** 2 + deflection_2d[0, 1] ** 2) assert deflection_r == pytest.approx(0.006034319441107217, 1.0e-8) diff --git a/test_autogalaxy/profiles/mass/dark/test_nfw_mcr.py b/test_autogalaxy/profiles/mass/dark/test_nfw_mcr.py index 47964eb69..b2aff11ca 100644 --- a/test_autogalaxy/profiles/mass/dark/test_nfw_mcr.py +++ b/test_autogalaxy/profiles/mass/dark/test_nfw_mcr.py @@ -7,9 +7,9 @@ def test__mass_and_concentration_consistent_with_normal_nfw(): - from autogalaxy.cosmology.model import FlatLambdaCDMWrap + from autogalaxy.cosmology.model import FlatLambdaCDM - cosmology = FlatLambdaCDMWrap(H0=70.0, Om0=0.3) + cosmology = FlatLambdaCDM(H0=70.0, Om0=0.3) mp = ag.mp.NFWMCRDuffySph( centre=(1.0, 2.0), @@ -56,9 +56,9 @@ def test__mass_and_concentration_consistent_with_normal_nfw(): def test__mass_and_concentration_consistent_with_normal_nfw__scatter_0(): - from autogalaxy.cosmology.model import FlatLambdaCDMWrap + from autogalaxy.cosmology.model import FlatLambdaCDM - cosmology = FlatLambdaCDMWrap(H0=70.0, Om0=0.3) + cosmology = FlatLambdaCDM(H0=70.0, Om0=0.3) mp = ag.mp.NFWMCRLudlowSph( centre=(1.0, 2.0), @@ -106,9 +106,9 @@ def test__mass_and_concentration_consistent_with_normal_nfw__scatter_0(): def test__same_as_above_but_elliptical(): - from autogalaxy.cosmology.model import FlatLambdaCDMWrap + from autogalaxy.cosmology.model import FlatLambdaCDM - cosmology = FlatLambdaCDMWrap(H0=70.0, Om0=0.3) + cosmology = FlatLambdaCDM(H0=70.0, Om0=0.3) mp = ag.mp.NFWMCRLudlow( centre=(1.0, 2.0), @@ -162,9 +162,9 @@ def test__same_as_above_but_elliptical(): def test__same_as_above_but_generalized_elliptical(): - from autogalaxy.cosmology.model import FlatLambdaCDMWrap + from autogalaxy.cosmology.model import FlatLambdaCDM - cosmology = FlatLambdaCDMWrap(H0=70.0, Om0=0.3) + cosmology = FlatLambdaCDM(H0=70.0, Om0=0.3) mp = ag.mp.gNFWMCRLudlow( centre=(1.0, 2.0), @@ -217,19 +217,20 @@ def test__same_as_above_but_generalized_elliptical(): assert (deflections_ludlow == deflections).all() + def test__same_as_above_but_cored_nfw(): - from autogalaxy.cosmology.model import FlatLambdaCDMWrap + from autogalaxy.cosmology.model import FlatLambdaCDM - cosmology = FlatLambdaCDMWrap(H0=70.0, Om0=0.3) + cosmology = FlatLambdaCDM(H0=70.0, Om0=0.3) mp = ag.mp.cNFWMCRLudlowSph( - centre=(1.0, 2.0), - mass_at_200=1.0e9, - f_c=0.01, - redshift_object=0.6, - redshift_source=2.5, - ) + centre=(1.0, 2.0), + mass_at_200=1.0e9, + f_c=0.01, + redshift_object=0.6, + redshift_source=2.5, + ) mass_at_200_via_mass = mp.mass_at_200_solar_masses( redshift_object=0.6, redshift_source=2.5, cosmology=cosmology @@ -239,17 +240,17 @@ def test__same_as_above_but_cored_nfw(): ) cnfw_kappa_s = ag.mp.cNFWSph( - centre=(1.0, 2.0), - kappa_s=mp.kappa_s, - scale_radius=mp.scale_radius, - core_radius=mp.core_radius, - ) + centre=(1.0, 2.0), + kappa_s=mp.kappa_s, + scale_radius=mp.scale_radius, + core_radius=mp.core_radius, + ) mass_at_200_via_kappa_s = cnfw_kappa_s.mass_at_200_solar_masses( - redshift_object=0.6, redshift_source=2.5, cosmology=cosmology + redshift_object=0.6, redshift_source=2.5, cosmology=cosmology ) concentration_via_kappa_s = cnfw_kappa_s.concentration( - redshift_profile=0.6, redshift_source=2.5, cosmology=cosmology + redshift_profile=0.6, redshift_source=2.5, cosmology=cosmology ) # We are using the NFWTruncatedSph to check the mass gives a consistent kappa_s, given certain radii. diff --git a/test_autogalaxy/profiles/mass/dark/test_nfw_truncated_mcr.py b/test_autogalaxy/profiles/mass/dark/test_nfw_truncated_mcr.py index 99188189b..7e22856af 100644 --- a/test_autogalaxy/profiles/mass/dark/test_nfw_truncated_mcr.py +++ b/test_autogalaxy/profiles/mass/dark/test_nfw_truncated_mcr.py @@ -8,9 +8,9 @@ def test__duffy__mass_and_concentration_consistent_with_normal_truncated_nfw(): - from autogalaxy.cosmology.model import FlatLambdaCDMWrap + from autogalaxy.cosmology.model import FlatLambdaCDM - cosmology = FlatLambdaCDMWrap(H0=70.0, Om0=0.3) + cosmology = FlatLambdaCDM(H0=70.0, Om0=0.3) mp = ag.mp.NFWTruncatedMCRDuffySph( centre=(1.0, 2.0), @@ -55,9 +55,9 @@ def test__duffy__mass_and_concentration_consistent_with_normal_truncated_nfw(): def test__ludlow__mass_and_concentration_consistent_with_normal_truncated_nfw__scatter_0(): - from autogalaxy.cosmology.model import FlatLambdaCDMWrap + from autogalaxy.cosmology.model import FlatLambdaCDM - cosmology = FlatLambdaCDMWrap(H0=70.0, Om0=0.3) + cosmology = FlatLambdaCDM(H0=70.0, Om0=0.3) mp = ag.mp.NFWTruncatedMCRLudlowSph( centre=(1.0, 2.0), diff --git a/test_autogalaxy/profiles/mass/stellar/test_gaussian.py b/test_autogalaxy/profiles/mass/stellar/test_gaussian.py index 2f0721a8a..151487d9f 100644 --- a/test_autogalaxy/profiles/mass/stellar/test_gaussian.py +++ b/test_autogalaxy/profiles/mass/stellar/test_gaussian.py @@ -67,7 +67,7 @@ def test__deflections_2d_via_analytic_from(): assert deflections[0, 0] == pytest.approx(1.10812, 1.0e-4) assert deflections[0, 1] == pytest.approx(0.35467, 1.0e-4) -@pytest.mark.skip(reason="Not JAX compatible") + def test__deflections_2d_via_integral_from(): mp = ag.mp.Gaussian( centre=(0.0, 0.0), @@ -137,7 +137,7 @@ def test__deflections_2d_via_integral_from(): assert deflections == pytest.approx(deflections_via_analytic.array, 1.0e-3) -@pytest.mark.skip(reason="Not JAX compatible") + def test__deflections_yx_2d_from(): mp = ag.mp.Gaussian()