From b46e438b440ea319e65ea325bdd87d84301c798d Mon Sep 17 00:00:00 2001 From: Jack O'Donnell <jacksonhodonnell@gmail.com> Date: Thu, 5 Oct 2023 15:22:01 -0700 Subject: [PATCH] first draft universal NFW with colossus --- autogalaxy/profiles/mass/dark/mcr_util.py | 88 +++++++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/autogalaxy/profiles/mass/dark/mcr_util.py b/autogalaxy/profiles/mass/dark/mcr_util.py index f3fc0119..738f9fe7 100644 --- a/autogalaxy/profiles/mass/dark/mcr_util.py +++ b/autogalaxy/profiles/mass/dark/mcr_util.py @@ -3,9 +3,90 @@ import numpy as np import warnings +from colossus.cosmology import cosmology as col_cosmology +from colossus.halo import profile_nfw +from colossus.halo.concentration import concentration as col_concentration + +from autogalaxy.cosmology.lensing import LensingCosmology from autogalaxy.cosmology.wrap import Planck15 +def set_colossus_cosmo(cosmology: LensingCosmology, sigma8=None, ns=None): + + if sigma8 is None or ns is None: + try: + cur_cosmo = col_cosmology.getCurrent() + except Exception: + col_cosmology.setCosmology('planck15') + cur_cosmo = col_cosmology.getCurrent() + sigma8 = cur_cosmo.sigma8 + ns = cur_cosmo.ns + + col_cosmo_obj = col_cosmology.fromAstropy(cosmology, sigma8, ns, '') + col_cosmology.setCurrent(col_cosmo_obj) + + return col_cosmo_obj + + +def physical_nfw_to_autogalaxy( + mass, concentration, mdef, redshift_object, redshift_source, + cosmology: LensingCosmology, + sigma8=None, ns=None, + ): + ''' + General function to convert an NFW Spherical Overdensity (M, concentration) + to AutoGalaxy parameters (kappa_s, scale_radius), for any cosmology and mass + definition. + + Under the hood this uses Colossus to compute everything, and can therefore + use any `mdef` that colossus understands, such as `vir`, `200m`, `500c`, etc. + (https://bdiemer.bitbucket.io/colossus/halo_profile_nfw.html) + + Parameters + ---------- + mass + Halo mass in solar masses. + concentration + NFW concentration. unitless. + mdef + Spherical overdensity mass definition, interpreted by colossus. Should be a string \ + such as 'vir', '200m', '200c', etc. + redshift_object + The redshift of the NFW halo. + redshift_source: + The redshift of the source. If the lensing model has multiple sources, \ + this should be the highest-redshift source. + cosmology + The cosmology to be used for the computation. + + Returns + ------- + 3-tuple of (kappa_s, scale_radius, r200) + ''' + col_cosmo_obj = set_colossus_cosmo(cosmology, sigma8, ns) + + halo = profile_nfw.NFWProfile( + M=mass*col_cosmo_obj.h(), c=concentration, z=redshift_object, mdef=mdef + ) + + critical_surface_density = ( + cosmology.critical_surface_density_between_redshifts_solar_mass_per_kpc2_from( + redshift_0=redshift_object, redshift_1=redshift_source + ) + ) + kpc_per_arcsec = cosmology.kpc_per_arcsec_from(redshift=redshift_object) + + # rho_s in Msun kpc-3, and rs in kpc + rho_s = halo.par['rhos']*col_cosmo_obj.h()**2 + rs = halo.par['rs']/col_cosmo_obj.h() + r200 = rs * concentration + + kappa_s = rho_s * rs / critical_surface_density + scale_radius = rs / kpc_per_arcsec + + return kappa_s, scale_radius, r200 + + def kappa_s_and_scale_radius_for_duffy(mass_at_200, redshift_object, redshift_source): """ Computes the AutoGalaxy NFW parameters (kappa_s, scale_radius) for an NFW halo of the given @@ -58,15 +139,12 @@ def kappa_s_and_scale_radius_for_duffy(mass_at_200, redshift_object, redshift_so def kappa_s_and_scale_radius_for_ludlow( mass_at_200, scatter_sigma, redshift_object, redshift_source ): - """ + ''' Computes the AutoGalaxy NFW parameters (kappa_s, scale_radius) for an NFW halo of the given mass, enforcing the Ludlow '16 mass-concentration relation. Interprets mass as *`M_{200c}`*, not `M_{200m}`. - """ - from colossus.cosmology import cosmology as col_cosmology - from colossus.halo.concentration import concentration as col_concentration - + ''' warnings.filterwarnings("ignore") cosmology = Planck15()