def solve_from_Mz(M, z, cross_section_type, kwargs_cross_section, z_collapse=10., include_c_scatter=False, c_scatter_add_dex=0., **kwargs_solver): """ This routine solves for the SIDM central density given the normalization of an NFW halo rhos, the scale radius rs, and a specific interaction cross section """ try: from pyHalo.Halos.lens_cosmo import LensCosmo from pyHalo.Cosmology.cosmology import Cosmology cosmo = Cosmology() lens_cosmo = LensCosmo() except: raise Exception( 'error importing pyHalo, which is needed to use this routine') c = lens_cosmo.NFW_concentration(M, z, scatter=include_c_scatter) if include_c_scatter is False and c_scatter_add_dex != 0: c = 10**(np.log10(c) + c_scatter_add_dex) rhos, rs, _ = lens_cosmo.NFW_params_physical(M, c, z) halo_age = cosmo.halo_age(z, z_collapse) if halo_age < 0.: raise Exception( 'the halo age is negative, you have probably specified a collapse redshift < halo redshift' ) return solve_from_NFW_params(rhos, rs, halo_age, cross_section_type, kwargs_cross_section, **kwargs_solver)
def delta_sigma_kawai(r, dm_fraction, lambda_dB, halo_mass, halo_redshift, mc_scatter=True): """ Returns standard deviation of the density fluctuations in projection in convergence units using Equation 30 in Kawai et al. (2021) :param r: the radius at which to evaluate the fluctuation amplitude [units kpc] :param f: the fraction of projected mass in dark matter at the radius r :param lambda_dB: de Broglie wavelength in kpc :param rhos: the density normalization of NFW proifle :param rs: the scale radius of NFW profile :param concentration: :param mc_scatter: :return: """ l = LensCosmo() c = l.NFW_concentration(halo_mass, halo_redshift, scatter=mc_scatter) rhos, rs, _ = l.NFW_params_physical(halo_mass, c, halo_redshift) halo_size = effective_halo_size(r, rhos, rs, c) relative_length_scale = lambda_dB / halo_size prefactor = 16 * np.pi**2 / 3 # extra 4pi from # integrating over the exponential delta_kappa_square = dm_fraction**2 * prefactor * relative_length_scale return delta_kappa_square**0.5
def setup(self): kwargs_cosmo = {'Om0': 0.2} self.cosmo = Cosmology(cosmo_kwargs=kwargs_cosmo) zlens, zsource = 0.3, 1.7 self.lens_cosmo = LensCosmo(zlens, zsource, self.cosmo) self.h = self.cosmo.h self.con = Concentration(self.lens_cosmo) self._colossus_nfw = NFWProfile
def delta_kappa(z_lens, z_source, m, rein, de_Broglie_wavelength): ''' Returns standard deviation of the density fluctuations in projection in convergence units :param z_lens,z_source: lens and source redshifts :param m: main deflector halo mass in M_solar :param rein: Einstein radius in kpc :param de_Broglie_wavelength: de Broglie wavelength of axion in kpc ''' l = LensCosmo(z_lens, z_source) sigma_crit = l.get_sigma_crit_lensing(z_lens, z_source) * (1e-3)**2 ds = delta_sigma(m, z_lens, rein, de_Broglie_wavelength) delta_kappa = ds / sigma_crit return delta_kappa
def delta_sigma(m, z, rein, de_Broglie_wavelength): """ Returns the mean ULDM fluctuation ampltiude of the host dark matter halo in units M_sun/kpc^2 :param m: :param z: :param rein: :param de_Broglie_wavelength: :return: """ l = LensCosmo(None, None) c = l.NFW_concentration(m, z, scatter=False) rhos, rs, _ = l.NFW_params_physical(m, c, z) nfw_rho_squared = projected_density_squared(rein, rhos, rs, c) delta_sigma = (np.sqrt(np.pi) * nfw_rho_squared * de_Broglie_wavelength)**0.5 return delta_sigma
def __init__(self, halo_mass, x, y, mdef, z, zlens, zsource, r3d=None, subhalo_flag=False, kwargs_halo={}, cosmo=None): """ Useful for generating a realization with a single or a few user-specified halos. :param halo_mass: mass of the halo in M_sun :param x: halo x coordinate in arcsec :param y: halo y coordinate in arcsec :param mdef: halo mass definition :param z: halo redshift :param zlens: main deflector redshift :param zsource: source redshift :param r3d: three dimensional coordinate of halo inside the host in kpc (only relevant for tidally-truncated subhalos, for field halos this can be None) :param subhalo_flag: bool, sets whether or not a halo is a subhalo :param kwargs_halo: keyword arguments for the halo :param cosmo: an instance of Cosmology(); if none is provided a default cosmology will be used """ if cosmo is None: cosmo = Cosmology() lens_cosmo = LensCosmo(zlens, zsource, cosmo) # these are redundant keywords for a single halo, but we need to specify them anyways kwargs_halo.update({'cone_opening_angle': 6., 'log_mlow': 6., 'log_mhigh': 10.}) super(SingleHalo, self).__init__([halo_mass], [x], [y], [r3d], [mdef], [z], [subhalo_flag], lens_cosmo, kwargs_realization=kwargs_halo, mass_sheet_correction=False)
def setup(self): mass = 10**7. x = 0.5 y = 1. r3d = np.sqrt(1 + 0.5 ** 2 + 70**2) self.r3d = r3d mdef = 'PJAFFE' self.z = 0.25 sub_flag = True self.H0 = 70 self.omega_baryon = 0.03 self.omega_DM = 0.25 self.sigma8 = 0.82 curvature = 'flat' self.ns = 0.9608 cosmo_params = {'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon, 'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature} self._dm, self._bar = self.omega_DM, self.omega_baryon cosmo = Cosmology(cosmo_kwargs=cosmo_params) self.lens_cosmo = LensCosmo(self.z, 2., cosmo) kwargs_suppression = {'c_scale': 10.5, 'c_power': -0.2} suppression_model = 'polynomial' profile_args = {'RocheNorm': 1.2, 'RocheNu': 2/3, 'evaluate_mc_at_zlens': True, 'log_mc': 0., 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'c_scatter': False, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'mc_mdef': '200c', 'c_scatter_dex': 0.1} self.profile_args = profile_args self.mass_subhalo = mass self.subhalo = PJaffeSubhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) mass_field_halo = 10 ** 7. sub_flag = False self.mass_field_halo = mass_field_halo self.field_halo = PJaffeSubhalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self._model_lenstronomy = PJaffe()
def delta_sigmaNFW(z_lens, m, rein, de_Broglie_wavelength): ''' Returns standard deviation of the density fluctuations in projection normalized by the projected density of the host halo :param z_lens,z_source: lens and source redshifts :param m: main deflector halo mass in M_solar :param rein: Einstein radius in kpc :param de_Broglie_wavelength: de Broglie wavelength of axion in kpc ''' l = LensCosmo(None, None) c = l.NFW_concentration(m, z_lens, scatter=False) rhos, rs, _ = l.NFW_params_physical(m, c, z_lens) kappa_host = projected_squared_density(rein, rhos, rs, c)**0.5 ds = delta_sigma(m, z_lens, rein, de_Broglie_wavelength) return ds / kappa_host
def setup(self): zlens, zsource = 0.5, 1.5 self.rs = 60 self.rmax2d = 40 self.rvir = 350 self.rcore = 10. self.nfw = ProjectedNFW(self.rmax2d, self.rs, self.rcore, self.rvir) cosmo = Cosmology() self.geometry = Geometry(cosmo, 0.5, 1.5, 6., 'DOUBLE_CONE') self.lens_cosmo = LensCosmo(zlens, zsource, cosmo)
def render(self, population_model_list, model_keywords, nrealizations=1, convergence_sheet_correction=True): halo_mass_function = self.build_LOS_mass_function(model_keywords) geometry = self.halo_mass_function.geometry keywords_master = set_default_kwargs(model_keywords, self.zsource) lens_cosmo = LensCosmo(self.zlens, self.zsource, self.cosmology) plane_redshifts, redshift_spacing = self.lens_plane_redshifts( keywords_master) realization_list = [] for n in range(nrealizations): population_model = HaloPopulation(population_model_list, keywords_master, lens_cosmo, geometry, halo_mass_function, plane_redshifts, redshift_spacing) masses, x_arcsec, y_arcsec, r3d, redshifts, subhalo_flag = population_model.render( ) mdefs = [] for i in range(0, len(masses)): if subhalo_flag[i]: mdefs += [keywords_master['mdef_subs']] else: mdefs += [keywords_master['mdef_los']] realization = Realization( masses, x_arcsec, y_arcsec, r3d, mdefs, redshifts, subhalo_flag, lens_cosmo, kwargs_realization=keywords_master, mass_sheet_correction=convergence_sheet_correction, rendering_classes=population_model.rendering_classes, geometry=geometry) realization_list.append(realization) return realization_list
def setup(self): mass = 10**8. x = 0.5 y = 1. z = 0.9 r3d = np.sqrt(1 + 0.5**2 + 70**2) self.r3d = r3d mdef = 'GAUSSIAN_KAPPA' self.z = z self.H0 = 70 self.omega_baryon = 0.03 self.omega_DM = 0.25 self.sigma8 = 0.82 curvature = 'flat' self.ns = 0.9608 cosmo_params = { 'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon, 'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature } cosmo = Cosmology(cosmo_kwargs=cosmo_params) self.lens_cosmo = LensCosmo(self.z, 2., cosmo) profile_args = {'amp': 1, 'sigma': 1, 'center_x': 0, 'center_y': 0} sub_flag = False self.halo = Gaussian(mass, x, y, r3d, mdef, z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand())
def setup(self): mass = 1e9 x = 0.5 y = 1. r3d = np.sqrt(1 + 0.5 ** 2 + 70**2) self.r3d = r3d self.z = 0.25 sub_flag = True mdef = 'ULDM' self.H0 = 70 self.omega_baryon = 0.03 self.omega_DM = 0.25 self.sigma8 = 0.82 curvature = 'flat' self.ns = 0.9608 cosmo_params = {'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon, 'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature} self._dm, self._bar = self.omega_DM, self.omega_baryon cosmo = Cosmology(cosmo_kwargs=cosmo_params) self.lens_cosmo = LensCosmo(self.z, 2., cosmo) kwargs_suppression = {'c_scale': 60., 'c_power': -0.17} suppression_model = 'polynomial' profile_args = {'RocheNorm': 1.2, 'RocheNu': 2/3, 'evaluate_mc_at_zlens': False, 'log_mc': None, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'c_scatter': False, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'c_scatter_dex': 0.1, 'mc_mdef': '200c', 'log10_m_uldm':-22, 'uldm_plaw':1/3} self.subhalo = ULDMSubhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self.fieldhalo = ULDMFieldHalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand())
def setup(self): mass = 10**8. x = 0.5 y = 1. r3d = np.sqrt(1 + 0.5**2 + 70**2) self.r3d = r3d mdef = 'coreTNFW' self.z = 0.25 sub_flag = True self.H0 = 70 self.omega_baryon = 0.03 self.omega_DM = 0.25 self.sigma8 = 0.82 curvature = 'flat' self.ns = 0.9608 cosmo_params = { 'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon, 'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature } self._dm, self._bar = self.omega_DM, self.omega_baryon cosmo = Cosmology(cosmo_kwargs=cosmo_params) self.lens_cosmo = LensCosmo(self.z, 2., cosmo) cross_section_type = 'POWER_LAW' self._cross_norm = 5 cross_section_kwargs = { 'norm': self._cross_norm, 'v_dep': 0.5, 'v_ref': 30. } kwargs_suppression = {'c_scale': 10.5, 'c_power': -0.2} suppression_model = 'polynomial' profile_args = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': None, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'c_scatter': False, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'c_scatter_dex': 0.1, 'mc_mdef': '200c', 'cross_section_type': cross_section_type, 'kwargs_cross_section': cross_section_kwargs, 'numerical_deflection_angle_class': self._deflection_function, 'SIDM_rhocentral_function': self._rho_function } self.profile_args = profile_args self.mass = mass self.subhalo = coreTNFWSubhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self.field_halo = coreTNFWFieldHalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand())
class TestcoreTNFWHalos(object): def setup(self): mass = 10**8. x = 0.5 y = 1. r3d = np.sqrt(1 + 0.5**2 + 70**2) self.r3d = r3d mdef = 'coreTNFW' self.z = 0.25 sub_flag = True self.H0 = 70 self.omega_baryon = 0.03 self.omega_DM = 0.25 self.sigma8 = 0.82 curvature = 'flat' self.ns = 0.9608 cosmo_params = { 'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon, 'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature } self._dm, self._bar = self.omega_DM, self.omega_baryon cosmo = Cosmology(cosmo_kwargs=cosmo_params) self.lens_cosmo = LensCosmo(self.z, 2., cosmo) cross_section_type = 'POWER_LAW' self._cross_norm = 5 cross_section_kwargs = { 'norm': self._cross_norm, 'v_dep': 0.5, 'v_ref': 30. } kwargs_suppression = {'c_scale': 10.5, 'c_power': -0.2} suppression_model = 'polynomial' profile_args = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': None, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'c_scatter': False, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'c_scatter_dex': 0.1, 'mc_mdef': '200c', 'cross_section_type': cross_section_type, 'kwargs_cross_section': cross_section_kwargs, 'numerical_deflection_angle_class': self._deflection_function, 'SIDM_rhocentral_function': self._rho_function } self.profile_args = profile_args self.mass = mass self.subhalo = coreTNFWSubhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self.field_halo = coreTNFWFieldHalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) def _deflection_function(self, x, y, rs, r_core, r_trunc, norm): tnfw = TNFW() return tnfw.derivatives(x, y, rs, norm, r_trunc) def _rho_function(self, m, z, delta_c_dex, cross_section_type, kwargs_cross_section): return kwargs_cross_section['norm'] def test_lenstronomy_kwargs(self): prof = self.field_halo (c, rtrunc_kpc, rho_central) = prof.profile_args kwargs, func = prof.lenstronomy_params rs_angle, theta_rs = self.lens_cosmo.nfw_physical2angle( prof.mass, c, prof.z) rtrunc_angle = rtrunc_kpc / self.lens_cosmo.cosmo.kpc_proper_per_asec( prof.z) rhos_kpc, rs_kpc, _ = self.subhalo.lens_cosmo.NFW_params_physical( prof.mass, c, prof._tnfw.z_eval) npt.assert_almost_equal(prof.x, kwargs[0]['center_x']) npt.assert_almost_equal(prof.y, kwargs[0]['center_y']) npt.assert_almost_equal(rtrunc_angle, kwargs[0]['r_trunc']) npt.assert_almost_equal(rs_angle, kwargs[0]['Rs']) x, y, rs, r_core, r_trunc, norm = 0.1, 0.1, 1., 1., 0.5, 1. out = func(x, y, rs, r_core, r_trunc, norm) npt.assert_almost_equal( out, self._deflection_function(x, y, rs, r_core, r_trunc, norm)) def test_lenstronomy_ID(self): id = self.subhalo.lenstronomy_ID npt.assert_string_equal(id[0], 'NumericalAlpha') id = self.field_halo.lenstronomy_ID npt.assert_string_equal(id[0], 'NumericalAlpha') def test_z_infall(self): z_eval = self.subhalo._tnfw.z_eval npt.assert_equal(True, self.z <= z_eval) z_eval = self.field_halo._tnfw.z_eval npt.assert_equal(True, self.z == z_eval) def test_profile_args(self): profile_args = self.subhalo.profile_args (c, rt, rho0) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass, '200c', self.z, model='diemer19') npt.assert_almost_equal(c / con, 1, 2) trunc = self.profile_args['RocheNorm'] * (10 ** 8 / 10 ** 7) ** (1. / 3) * \ (self.r3d / 50) ** self.profile_args['RocheNu'] npt.assert_almost_equal(trunc, rt, 3) rho_central = self._cross_norm npt.assert_almost_equal(rho0, rho_central) profile_args = self.field_halo.profile_args (c, rt, rho0) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass, '200c', self.z, model='diemer19') npt.assert_almost_equal(c / con, 1, 2) m_h = self.mass * self.lens_cosmo.cosmo.h r50_comoving = self.lens_cosmo.rN_M_nfw_comoving( m_h, self.profile_args['LOS_truncation_factor'], self.z) r50_physical = r50_comoving * self.lens_cosmo.cosmo.scale_factor( self.z) / self.lens_cosmo.cosmo.h r50_physical_kpc = r50_physical * 1000 npt.assert_almost_equal(r50_physical_kpc, rt) rho_central = self._cross_norm npt.assert_almost_equal(rho0, rho_central) def test_fromTNFW(self): tnfw = TNFWSubhalo(self.subhalo.mass, self.subhalo.x, self.subhalo.y, self.subhalo.r3d, 'TNFW', self.subhalo.z, True, self.subhalo.lens_cosmo, self.profile_args, unique_tag=1.23) coreTNFW = coreTNFWSubhalo.fromTNFW(tnfw, kwargs_new=self.profile_args) npt.assert_almost_equal(coreTNFW.mass, tnfw.mass) npt.assert_almost_equal(coreTNFW.x, tnfw.x) npt.assert_almost_equal(coreTNFW.y, tnfw.y) npt.assert_almost_equal(coreTNFW.r3d, tnfw.r3d) prof_params = tnfw.profile_args prof_params_core = coreTNFW.profile_args for i in range(0, len(prof_params) - 1): npt.assert_almost_equal(prof_params[i], prof_params_core[i]) lenstronomy_params_tnfw, _ = tnfw.lenstronomy_params lenstronomy_params_coretnfw, _ = coreTNFW.lenstronomy_params npt.assert_almost_equal(lenstronomy_params_tnfw[0]['Rs'], lenstronomy_params_coretnfw[0]['Rs']) npt.assert_almost_equal(lenstronomy_params_tnfw[0]['r_trunc'], lenstronomy_params_coretnfw[0]['r_trunc']) tnfw = TNFWFieldHalo(self.subhalo.mass, self.subhalo.x, self.subhalo.y, self.subhalo.r3d, 'TNFW', self.subhalo.z, True, self.subhalo.lens_cosmo, self.profile_args, unique_tag=1.23) coreTNFW = coreTNFWFieldHalo.fromTNFW(tnfw, kwargs_new=self.profile_args) npt.assert_almost_equal(coreTNFW.mass, tnfw.mass) npt.assert_almost_equal(coreTNFW.x, tnfw.x) npt.assert_almost_equal(coreTNFW.y, tnfw.y) npt.assert_almost_equal(coreTNFW.r3d, tnfw.r3d) prof_params = tnfw.profile_args prof_params_core = coreTNFW.profile_args for i in range(0, len(prof_params) - 1): npt.assert_almost_equal(prof_params[i], prof_params_core[i]) lenstronomy_params_tnfw, _ = tnfw.lenstronomy_params lenstronomy_params_coretnfw, _ = coreTNFW.lenstronomy_params npt.assert_almost_equal(lenstronomy_params_tnfw[0]['Rs'], lenstronomy_params_coretnfw[0]['Rs']) npt.assert_almost_equal(lenstronomy_params_tnfw[0]['r_trunc'], lenstronomy_params_coretnfw[0]['r_trunc'])
def setup(self): zlens, zsource = 0.5, 2. zmin = 0.01 zmax = 1.98 log_mlow = 6. log_mhigh = 9. host_m200 = 10**13 LOS_normalization = 1. draw_poisson = False log_mass_sheet_min = 7. log_mass_sheet_max = 10. kappa_scale = 1. delta_power_law_index = -0.1 delta_power_law_index_coupling = 0.5 cone_opening_angle = 6. m_pivot = 10**8 sigma_sub = 0.1 power_law_index = -1.9 subhalo_spatial_distribution = 'HOST_NFW' kwargs_cdm = { 'zmin': zmin, 'zmax': zmax, 'log_mc': None, 'log_mlow': log_mlow, 'sigma_sub': sigma_sub, 'c_scale': None, 'c_power': None, 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'c_scatter_dex': 0.2, 'log_mhigh': log_mhigh, 'mdef_los': 'TNFW', 'host_m200': host_m200, 'LOS_normalization': LOS_normalization, 'draw_poisson': draw_poisson, 'subhalo_spatial_distribution': subhalo_spatial_distribution, 'log_mass_sheet_min': log_mass_sheet_min, 'log_mass_sheet_max': log_mass_sheet_max, 'kappa_scale': kappa_scale, 'power_law_index': power_law_index, 'delta_power_law_index': delta_power_law_index, 'delta_power_law_index_coupling': delta_power_law_index_coupling, 'm_pivot': m_pivot, 'cone_opening_angle': cone_opening_angle, 'subhalo_mass_sheet_scale': 1., 'subhalo_convergence_correction_profile': 'NFW', 'r_tidal': '0.5Rs' } pyhalo = pyHalo(zlens, zsource) self.realization_cdm = pyhalo.render(['TWO_HALO'], kwargs_cdm)[0] lens_plane_redshifts, delta_zs = pyhalo.lens_plane_redshifts( kwargs_cdm) cosmo = Cosmology() self.lens_plane_redshifts = lens_plane_redshifts self.delta_zs = delta_zs self.halo_mass_function = LensingMassFunction( cosmo, zlens, zsource, kwargs_cdm['log_mlow'], kwargs_cdm['log_mhigh'], kwargs_cdm['cone_opening_angle'], m_pivot=kwargs_cdm['m_pivot'], geometry_type='DOUBLE_CONE') self.geometry = Geometry(cosmo, zlens, zsource, kwargs_cdm['cone_opening_angle'], 'DOUBLE_CONE') self.lens_cosmo = LensCosmo(zlens, zsource, cosmo) self.kwargs_cdm = kwargs_cdm self.rendering_class = TwoHaloContribution( kwargs_cdm, self.halo_mass_function, self.geometry, self.lens_cosmo, self.lens_plane_redshifts, self.delta_zs)
class TestTNFWHalos(object): def setup(self): mass = 10**8. x = 0.5 y = 1. r3d = np.sqrt(1 + 0.5**2 + 70**2) self.r3d = r3d mdef = 'TNFW' self.z = 0.25 sub_flag = True self.H0 = 70 self.omega_baryon = 0.03 self.omega_DM = 0.25 self.sigma8 = 0.82 curvature = 'flat' self.ns = 0.9608 cosmo_params = { 'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon, 'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature } self._dm, self._bar = self.omega_DM, self.omega_baryon cosmo = Cosmology(cosmo_kwargs=cosmo_params) self.lens_cosmo = LensCosmo(self.z, 2., cosmo) kwargs_suppression = {'a_mc': 0.5, 'b_mc': 1.9} suppression_model = 'hyperbolic' profile_args = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': None, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'c_scatter': False, 'c_scatter_dex': 0.1, 'mc_mdef': '200c' } self.profile_args_WDM = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': 7.6, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'c_scatter': False, 'c_scatter_dex': 0.1, 'mc_mdef': '200c' } self._profile_args = profile_args self.mass_subhalo = mass self.subhalo = TNFWSubhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self.subhalo_WDM = TNFWSubhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_WDM, unique_tag=np.random.rand()) mass_field_halo = 10**7. sub_flag = False self.mass_field_halo = mass_field_halo self.field_halo = TNFWFieldHalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self.field_halo_WDM = TNFWFieldHalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_WDM, unique_tag=np.random.rand()) self.profile_args_custom = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': None, 'c_scatter': False, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'mc_model': { 'custom': True, 'c0': 6., 'beta': 0.2, 'zeta': -0.3 }, 'LOS_truncation_factor': 40, 'c_scatter_dex': 0.1, 'mc_mdef': '200c' } mdef = 'TNFW' sub_flag = False self.field_halo_custom = TNFWFieldHalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_custom, unique_tag=np.random.rand()) sub_flag = True self.subhalo_custom = TNFWSubhalo(self.mass_subhalo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_custom, unique_tag=np.random.rand()) self.profile_args_WDM_custom = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': 8., 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'c_scatter': False, 'mc_model': { 'custom': True, 'c0': 6., 'beta': 0.2, 'zeta': -0.3 }, 'LOS_truncation_factor': 40, 'c_scatter_dex': 0.1, 'mc_mdef': '200c' } sub_flag = True self.subhalo_custom_WDM = TNFWSubhalo(self.mass_subhalo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_WDM_custom, unique_tag=np.random.rand()) sub_flag = False self.field_halo_custom_WDM = TNFWFieldHalo( self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_WDM_custom, unique_tag=np.random.rand()) def test_lenstronomy_kwargs(self): for prof in [ self.subhalo_custom, self.subhalo, self.field_halo, self.field_halo_custom ]: (c, rtrunc_kpc) = prof.profile_args kwargs, other = prof.lenstronomy_params rs, theta_rs = self.lens_cosmo.nfw_physical2angle( prof.mass, c, self.z) names = ['center_x', 'center_y', 'alpha_Rs', 'Rs', 'r_trunc'] rtrunc_angle = rtrunc_kpc / self.lens_cosmo.cosmo.kpc_proper_per_asec( self.z) values = [prof.x, prof.y, theta_rs, rs, rtrunc_angle] for name, value in zip(names, values): npt.assert_almost_equal(kwargs[0][name], value) def test_lenstronomy_ID(self): id = self.subhalo_custom.lenstronomy_ID npt.assert_string_equal(id[0], 'TNFW') def test_z_infall(self): z_infall = self.subhalo.z_infall npt.assert_equal(True, self.z <= z_infall) def test_rescale_norm(self): kwargs_halo = {'c_scatter': True} realization = SingleHalo(10**9, 0., 0., 'TNFW', 0.6, 0.5, 1.5, subhalo_flag=False, kwargs_halo=kwargs_halo) lens_model_list, zlist, kwargs_init, _ = realization.lensing_quantities( False) realization_copy = deepcopy(realization) lens_model_list, zlist, kwargs_copy, _ = realization_copy.lensing_quantities( False) npt.assert_equal(kwargs_init[0]['alpha_Rs'], kwargs_copy[0]['alpha_Rs']) rescale = 0.7 realization.halos[0].rescale_normalization(rescale) realization_copy.halos[0].rescale_normalization(rescale) lens_model_list, zlist, kwargs, _ = realization.lensing_quantities( False) lens_model_list, zlist, kwargs_copy, _ = realization.lensing_quantities( False) npt.assert_equal(kwargs_init[0]['alpha_Rs'] * rescale, kwargs[0]['alpha_Rs']) npt.assert_equal(kwargs_init[0]['alpha_Rs'] * rescale, kwargs_copy[0]['alpha_Rs']) def test_profile_args(self): profile_args = self.subhalo.profile_args (c, rt) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_subhalo, '200c', self.z, model='diemer19') npt.assert_almost_equal(c / con, 1, 2) trunc = self._profile_args['RocheNorm'] * (10 ** 8 / 10 ** 7) ** (1./3) * \ (self.r3d / 50) ** self._profile_args['RocheNu'] npt.assert_almost_equal(trunc, rt, 3) profile_args = self.subhalo_WDM.profile_args (c, rt) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_subhalo, '200c', self.z, model='diemer19') amc, bmc = self.profile_args_WDM['kwargs_suppression']['a_mc'], \ self.profile_args_WDM['kwargs_suppression']['b_mc'] u = self.mass_subhalo / 10**self.profile_args_WDM['log_mc'] argument = (np.log10(u) - amc) / (2 * bmc) wdm_suppresion = 0.5 * (1 + np.tanh(argument)) npt.assert_almost_equal(con * wdm_suppresion, c) profile_args = self.field_halo.profile_args (c, rt) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_field_halo, '200c', self.z, model='diemer19') npt.assert_almost_equal(c / con, 1, 2) m_h = self.mass_field_halo * self.lens_cosmo.cosmo.h r50_comoving = self.lens_cosmo.rN_M_nfw_comoving( m_h, self._profile_args['LOS_truncation_factor'], self.z) r50_physical = r50_comoving * self.lens_cosmo.cosmo.scale_factor( self.z) / self.lens_cosmo.cosmo.h r50_physical_kpc = r50_physical * 1000 npt.assert_almost_equal(r50_physical_kpc, rt) profile_args = self.field_halo_WDM.profile_args (c, rt) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_field_halo, '200c', self.z, model='diemer19') amc, bmc = self.profile_args_WDM['kwargs_suppression']['a_mc'], \ self.profile_args_WDM['kwargs_suppression']['b_mc'] u = self.mass_field_halo / 10**self.profile_args_WDM['log_mc'] argument = (np.log10(u) - amc) / (2 * bmc) wdm_suppresion = 0.5 * (1 + np.tanh(argument)) npt.assert_almost_equal(con * wdm_suppresion, c) profile_args = self.subhalo_custom.profile_args (c, _) = profile_args c0 = self.profile_args_custom['mc_model']['c0'] beta = self.profile_args_custom['mc_model']['beta'] zeta = self.profile_args_custom['mc_model']['zeta'] h = self.lens_cosmo.cosmo.h mh_sub = self.mass_subhalo * h nu = peaks.peakHeight(mh_sub, self.z) nu_ref = peaks.peakHeight(h * 10**8, 0.) con_subhalo = c0 * (1 + self.z)**zeta * (nu / nu_ref)**-beta npt.assert_almost_equal(con_subhalo / c, 1) profile_args = self.field_halo_custom.profile_args (c, _) = profile_args c0 = self.profile_args_custom['mc_model']['c0'] beta = self.profile_args_custom['mc_model']['beta'] zeta = self.profile_args_custom['mc_model']['zeta'] h = self.lens_cosmo.cosmo.h mh_sub = self.mass_field_halo * h nu = peaks.peakHeight(mh_sub, self.z) nu_ref = peaks.peakHeight(h * 10**8, 0.) con_field_halo = c0 * (1 + self.z)**zeta * (nu / nu_ref)**-beta npt.assert_almost_equal(con_field_halo / c, 1) profile_args = self.field_halo_custom_WDM.profile_args (c, _) = profile_args c0 = self.profile_args_custom['mc_model']['c0'] beta = self.profile_args_custom['mc_model']['beta'] zeta = self.profile_args_custom['mc_model']['zeta'] u = self.mass_field_halo / 10**self.profile_args_WDM_custom['log_mc'] argument = (np.log10(u) - amc) / (2 * bmc) wdm_suppresion = 0.5 * (1 + np.tanh(argument)) h = self.lens_cosmo.cosmo.h mh_field = self.mass_field_halo * h nu = peaks.peakHeight(mh_field, self.z) nu_ref = peaks.peakHeight(h * 10**8, 0.) con_field_halo = c0 * (1 + self.z)**zeta * (nu / nu_ref)**-beta npt.assert_almost_equal(wdm_suppresion * con_field_halo, c)
class TestSubhalos(object): def setup(self): zlens, zsource = 0.5, 2. zmin = 0.01 zmax = 1.98 log_mlow = 6. log_mhigh = 9. host_m200 = 10**13.5 LOS_normalization = 1. draw_poisson = False log_mass_sheet_min = 7. log_mass_sheet_max = 10. kappa_scale = 1. delta_power_law_index = -0.1 delta_power_law_index_coupling = 0.5 cone_opening_angle = 6. m_pivot = 10**8 sigma_sub = 0.1 power_law_index = -1.9 subhalo_spatial_distribution = 'HOST_NFW' kwargs_cdm_uniform = { 'zmin': zmin, 'zmax': zmax, 'log_mc': None, 'log_mlow': log_mlow, 'sigma_sub': sigma_sub, 'c_scale': None, 'c_power': None, 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'c_scatter_dex': 0.2, 'log_mhigh': log_mhigh, 'mdef_subs': 'TNFW', 'log_m_host': np.log10(host_m200), 'LOS_normalization': LOS_normalization, 'draw_poisson': draw_poisson, 'subhalo_spatial_distribution': subhalo_spatial_distribution, 'log_mass_sheet_min': log_mass_sheet_min, 'log_mass_sheet_max': log_mass_sheet_max, 'kappa_scale': kappa_scale, 'power_law_index': power_law_index, 'delta_power_law_index': delta_power_law_index, 'delta_power_law_index_coupling': delta_power_law_index_coupling, 'm_pivot': m_pivot, 'cone_opening_angle': cone_opening_angle, 'subhalo_mass_sheet_scale': 1., 'subhalo_convergence_correction_profile': 'UNIFORM', 'r_tidal': '0.5Rs' } kwargs_cdm_nfw = deepcopy(kwargs_cdm_uniform) kwargs_cdm_nfw['subhalo_convergence_correction_profile'] = 'NFW' pyhalo = pyHalo(zlens, zsource) self.realization_cdm = pyhalo.render(['SUBHALOS'], kwargs_cdm_uniform)[0] self.realization_cdm_nfw = pyhalo.render(['SUBHALOS'], kwargs_cdm_nfw)[0] lens_plane_redshifts, delta_zs = pyhalo.lens_plane_redshifts( kwargs_cdm_uniform) cosmo = Cosmology() self.lens_plane_redshifts = lens_plane_redshifts self.delta_zs = delta_zs self.halo_mass_function = LensingMassFunction( cosmo, zlens, zsource, kwargs_cdm_uniform['log_mlow'], kwargs_cdm_uniform['log_mhigh'], kwargs_cdm_uniform['cone_opening_angle'], m_pivot=kwargs_cdm_uniform['m_pivot'], geometry_type='DOUBLE_CONE') self.geometry = Geometry(cosmo, zlens, zsource, kwargs_cdm_uniform['cone_opening_angle'], 'DOUBLE_CONE') self.lens_cosmo = LensCosmo(zlens, zsource, cosmo) self.kwargs_cdm = kwargs_cdm_uniform self.rendering_class_uniform = Subhalos(kwargs_cdm_uniform, self.geometry, self.lens_cosmo) self.rendering_class_nfw = Subhalos(kwargs_cdm_nfw, self.geometry, self.lens_cosmo) def test_normalization(self): norm = normalization_sigmasub( self.kwargs_cdm['sigma_sub'], 10**self.kwargs_cdm['log_m_host'], self.lens_cosmo.z_lens, self.geometry.kpc_per_arcsec_zlens, self.kwargs_cdm['cone_opening_angle'], self.kwargs_cdm['power_law_index'] + self.kwargs_cdm['delta_power_law_index'] * self.kwargs_cdm['delta_power_law_index_coupling'], self.kwargs_cdm['m_pivot']) k1, k2 = 0.88, 1.7 slope = self.kwargs_cdm['power_law_index'] + self.kwargs_cdm['delta_power_law_index'] * \ self.kwargs_cdm['delta_power_law_index_coupling'] mhalo = 10**self.kwargs_cdm['log_m_host'] scale = k1 * np.log10( mhalo / 10**13) + k2 * np.log10(self.lens_cosmo.z_lens + 0.5) host_scaling = 10**scale norm_theory = self.kwargs_cdm['sigma_sub'] * host_scaling kpc_per_arcsec_zlens = self.geometry.kpc_per_arcsec( self.lens_cosmo.z_lens) norm_theory *= np.pi * (0.5 * self.kwargs_cdm['cone_opening_angle'] * kpc_per_arcsec_zlens)**2 norm_theory *= self.kwargs_cdm['m_pivot']**-(slope + 1) npt.assert_almost_equal(norm, norm_theory) _norm, _slope = self.rendering_class_uniform._norm_slope() npt.assert_almost_equal(_norm, norm) npt.assert_almost_equal(_slope, slope) def test_rendering(self): m = self.rendering_class_uniform.render_masses_at_z() npt.assert_equal(True, len(m) > 0) x, y, r3 = self.rendering_class_uniform.render_positions_at_z(10000) rmax = np.max(np.hypot(x, y)) rmax_theory = 0.5 * self.kwargs_cdm[ 'cone_opening_angle'] * self.geometry.rendering_scale( self.lens_cosmo.z_lens) npt.assert_array_less(rmax, rmax_theory) x, y, r3 = self.rendering_class_uniform.render_positions_at_z(0) npt.assert_equal(True, len(x) == 0) m, x, y, r3, redshifts, flag = self.rendering_class_uniform.render() npt.assert_equal(len(m), len(x)) npt.assert_equal(len(y), len(r3)) n = 0 for z in np.unique(redshifts): n += np.sum(redshifts == z) npt.assert_equal(True, n == len(m)) npt.assert_equal(True, len(self.realization_cdm.halos) == len(m)) def test_convergence_correction(self): z = self.lens_cosmo.z_lens norm, slope = self.rendering_class_uniform._norm_slope() # factor of two because the kappa sheets are added at every other lens plane mtheory = integrate_power_law_analytic( norm, 10**self.kwargs_cdm['log_mass_sheet_min'], 10**self.kwargs_cdm['log_mass_sheet_max'], 1., slope) area = self.geometry.angle_to_physical_area( 0.5 * self.kwargs_cdm['cone_opening_angle'], z) kappa_theory = mtheory / self.lens_cosmo.sigma_crit_mass(z, area) kwargs_out, profile_names_out, redshifts = self.rendering_class_uniform.convergence_sheet_correction( ) kw = kwargs_out[0] name = profile_names_out[0] npt.assert_equal(True, name == 'CONVERGENCE') kappa_generated = -kw['kappa'] npt.assert_array_less(abs(kappa_theory / kappa_generated - 1), 0.05) def test_keys_convergence_sheets(self): keywords_out = self.rendering_class_uniform.keys_convergence_sheets( self.kwargs_cdm) required_keys = [ 'log_mass_sheet_min', 'log_mass_sheet_max', 'subhalo_mass_sheet_scale', 'subhalo_convergence_correction_profile', 'r_tidal', 'delta_power_law_index', 'delta_power_law_index_coupling' ] for x in required_keys: npt.assert_equal(x in keywords_out.keys(), True) def test_keys_rendering(self): keywords_out = self.rendering_class_uniform.keyword_parse_render( self.kwargs_cdm) required_keys = [ 'power_law_index', 'log_mlow', 'log_mhigh', 'log_mc', 'sigma_sub', 'a_wdm', 'b_wdm', 'c_wdm', 'log_mass_sheet_min', 'log_mass_sheet_max', 'subhalo_mass_sheet_scale', 'draw_poisson', 'host_m200', 'subhalo_convergence_correction_profile', 'r_tidal', 'delta_power_law_index', 'm_pivot', 'delta_power_law_index_coupling', 'cone_opening_angle' ] for x in required_keys: npt.assert_equal(x in keywords_out.keys(), True) kw_cdm = deepcopy(self.kwargs_cdm) kw_cdm['log_mc'] = None keywords_out = self.rendering_class_uniform.keyword_parse_render( kw_cdm) npt.assert_equal(keywords_out['a_wdm'] is None, True) npt.assert_equal(keywords_out['b_wdm'] is None, True) npt.assert_equal(keywords_out['c_wdm'] is None, True)
class TestNFWHalos(object): def setup(self): mass = 10**8. x = 0.5 y = 1. r3d = np.sqrt(1 + 0.5 ** 2 + 70**2) self.r3d = r3d mdef = 'TNFW' self.z = 1.2 sub_flag = True self.H0 = 70 self.omega_baryon = 0.03 self.omega_DM = 0.25 self.sigma8 = 0.82 curvature = 'flat' self.ns = 0.9608 cosmo_params = {'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon, 'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature} self._dm, self._bar = self.omega_DM, self.omega_baryon cosmo = Cosmology(cosmo_kwargs=cosmo_params) self.lens_cosmo = LensCosmo(self.z, 2., cosmo) kwargs_suppression = {'c_scale': 10.5, 'c_power': -0.2} suppression_model = 'polynomial' profile_args = {'RocheNorm': 1.2, 'RocheNu': 2/3, 'evaluate_mc_at_zlens': True, 'log_mc': None, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'c_scatter': False, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'mc_mdef': '200c', 'c_scatter_dex': 0.1} self._profile_args = profile_args self.mass_subhalo = mass self.subhalo = NFWSubhhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) mass_field_halo = 10 ** 7. sub_flag = False self.mass_field_halo = mass_field_halo self.field_halo = NFWFieldHalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self.profile_args_custom = {'RocheNorm': 1.2, 'RocheNu': 2/3, 'evaluate_mc_at_zlens': True, 'log_mc': None, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'c_scatter': False, 'mc_model': {'custom': True, 'c0': 28., 'beta': 1.2, 'zeta': -0.5}, 'LOS_truncation_factor': 40, 'mc_mdef': '200c', 'c_scatter_dex': 0.1} mdef = 'NFW' sub_flag = False self.field_halo_custom = NFWFieldHalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_custom, unique_tag=np.random.rand()) sub_flag = True self.subhalo_custom = NFWSubhhalo(self.mass_subhalo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_custom, unique_tag=np.random.rand()) def test_lenstronomy_ID(self): id = self.subhalo_custom.lenstronomy_ID npt.assert_string_equal(id[0], 'NFW') def test_z_infall(self): z_infall = self.subhalo.z_infall npt.assert_equal(True, self.z <= z_infall) def test_lenstronomy_kwargs(self): for prof in [self.subhalo_custom, self.subhalo, self.field_halo, self.field_halo_custom]: (c) = prof.profile_args kwargs, other = prof.lenstronomy_params rs, theta_rs = self.lens_cosmo.nfw_physical2angle(prof.mass, c, self.z) names = ['center_x', 'center_y', 'alpha_Rs', 'Rs'] values = [prof.x, prof.y, theta_rs, rs] for name, value in zip(names, values): npt.assert_almost_equal(kwargs[0][name]/value, 1, 5) def test_profile_args(self): profile_args = self.subhalo.profile_args (c) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_subhalo, '200c', self.z, model='diemer19') npt.assert_almost_equal(c/con, 1, 2) profile_args = self.field_halo.profile_args (c) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_field_halo, '200c', self.z, model='diemer19') npt.assert_almost_equal(c / con, 1, 2) profile_args = self.subhalo_custom.profile_args (c) = profile_args c0 = self.profile_args_custom['mc_model']['c0'] beta = self.profile_args_custom['mc_model']['beta'] zeta = self.profile_args_custom['mc_model']['zeta'] h = self.lens_cosmo.cosmo.h mh_sub = self.mass_subhalo * h nu = peaks.peakHeight(mh_sub, self.z) nu_ref = peaks.peakHeight(h * 10 ** 8, 0.) con_subhalo = c0 * (1 + self.z) ** zeta * (nu / nu_ref) ** -beta npt.assert_almost_equal(con_subhalo/c, 1, 2) profile_args = self.field_halo_custom.profile_args (c) = profile_args c0 = self.profile_args_custom['mc_model']['c0'] beta = self.profile_args_custom['mc_model']['beta'] zeta = self.profile_args_custom['mc_model']['zeta'] h = self.lens_cosmo.cosmo.h mh_sub = self.mass_field_halo * h nu = peaks.peakHeight(mh_sub, self.z) nu_ref = peaks.peakHeight(h * 10 ** 8, 0.) con_field_halo = c0 * (1 + self.z) ** zeta * (nu / nu_ref) ** -beta npt.assert_almost_equal(con_field_halo / c, 1, 2)
class TestPjaffeHalo(object): def setup(self): mass = 10**7. x = 0.5 y = 1. r3d = np.sqrt(1 + 0.5 ** 2 + 70**2) self.r3d = r3d mdef = 'PJAFFE' self.z = 0.25 sub_flag = True self.H0 = 70 self.omega_baryon = 0.03 self.omega_DM = 0.25 self.sigma8 = 0.82 curvature = 'flat' self.ns = 0.9608 cosmo_params = {'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon, 'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature} self._dm, self._bar = self.omega_DM, self.omega_baryon cosmo = Cosmology(cosmo_kwargs=cosmo_params) self.lens_cosmo = LensCosmo(self.z, 2., cosmo) kwargs_suppression = {'c_scale': 10.5, 'c_power': -0.2} suppression_model = 'polynomial' profile_args = {'RocheNorm': 1.2, 'RocheNu': 2/3, 'evaluate_mc_at_zlens': True, 'log_mc': 0., 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'c_scatter': False, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'mc_mdef': '200c', 'c_scatter_dex': 0.1} self.profile_args = profile_args self.mass_subhalo = mass self.subhalo = PJaffeSubhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) mass_field_halo = 10 ** 7. sub_flag = False self.mass_field_halo = mass_field_halo self.field_halo = PJaffeSubhalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self._model_lenstronomy = PJaffe() def test_lenstronomy_ID(self): id = self.subhalo.lenstronomy_ID npt.assert_string_equal(id[0], 'PJAFFE') id = self.field_halo.lenstronomy_ID npt.assert_string_equal(id[0], 'PJAFFE') def test_z_infall(self): z_infall = self.subhalo.z_infall npt.assert_equal(True, self.z <= z_infall) def test_total_mass(self): c = float(self.subhalo.profile_args) rhos, rs, r200 = self.lens_cosmo.NFW_params_physical(self.subhalo.mass, c, self.z) fc = np.log(1 + c) - c / (1 + c) m_nfw = 4 * np.pi * rs ** 3 * rhos * fc lenstronomy_kwargs, _ = self.subhalo.lenstronomy_params sigma0, ra, rs = lenstronomy_kwargs[0]['sigma0'], lenstronomy_kwargs[0]['Ra'], lenstronomy_kwargs[0]['Rs'] arcsec_to_kpc = self.lens_cosmo.cosmo.kpc_proper_per_asec(self.z) ra *= arcsec_to_kpc ** -1 rs *= arcsec_to_kpc ** -1 rho = self.subhalo._rho(m_nfw, rs, ra, c*rs) m3d = self._model_lenstronomy.mass_3d(c*rs, rho, ra, rs) npt.assert_almost_equal(np.log10(m3d), np.log10(m_nfw)) def test_profile_args(self): profile_args = self.subhalo.profile_args (c) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_subhalo, '200c', self.z, model='diemer19') npt.assert_almost_equal(c/con, 1, 2) profile_args = self.field_halo.profile_args (c) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_field_halo, '200c', self.z, model='diemer19') npt.assert_almost_equal(c / con, 1, 2) profile_args = self.field_halo.profile_args (c) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_subhalo, '200c', self.z, model='diemer19') npt.assert_almost_equal(c / con, 1, 2) profile_args = self.field_halo.profile_args (c) = profile_args con = concentration(self.lens_cosmo.cosmo.h * self.mass_field_halo, '200c', self.z, model='diemer19') npt.assert_almost_equal(c / con, 1, 2) def test_params_physical(self): params_physical = self.subhalo.params_physical npt.assert_equal(len(params_physical), 4)
class TestLOS(object): def setup(self): zlens, zsource = 0.5, 2. zmin = 0.01 zmax = 1.98 log_mlow = 6. log_mhigh = 9. host_m200 = 10**13 LOS_normalization = 1. draw_poisson = False log_mass_sheet_min = 7. log_mass_sheet_max = 10. kappa_scale = 1. delta_power_law_index = -0.1 delta_power_law_index_coupling = 0.5 cone_opening_angle = 6. m_pivot = 10**8 sigma_sub = 0.1 power_law_index = -1.9 subhalo_spatial_distribution = 'HOST_NFW' kwargs_cdm = { 'zmin': zmin, 'zmax': zmax, 'log_mc': None, 'log_mlow': log_mlow, 'sigma_sub': sigma_sub, 'c_scale': None, 'c_power': None, 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'c_scatter_dex': 0.2, 'log_mhigh': log_mhigh, 'mdef_los': 'TNFW', 'host_m200': host_m200, 'LOS_normalization': LOS_normalization, 'draw_poisson': draw_poisson, 'subhalo_spatial_distribution': subhalo_spatial_distribution, 'log_mass_sheet_min': log_mass_sheet_min, 'log_mass_sheet_max': log_mass_sheet_max, 'kappa_scale': kappa_scale, 'power_law_index': power_law_index, 'delta_power_law_index': delta_power_law_index, 'delta_power_law_index_coupling': delta_power_law_index_coupling, 'm_pivot': m_pivot, 'cone_opening_angle': cone_opening_angle, 'subhalo_mass_sheet_scale': 1., 'subhalo_convergence_correction_profile': 'NFW', 'r_tidal': '0.5Rs' } pyhalo = pyHalo(zlens, zsource) self.realization_cdm = pyhalo.render(['LINE_OF_SIGHT'], kwargs_cdm)[0] lens_plane_redshifts, delta_zs = pyhalo.lens_plane_redshifts( kwargs_cdm) cosmo = Cosmology() self.lens_plane_redshifts = lens_plane_redshifts self.delta_zs = delta_zs self.halo_mass_function = LensingMassFunction( cosmo, zlens, zsource, kwargs_cdm['log_mlow'], kwargs_cdm['log_mhigh'], kwargs_cdm['cone_opening_angle'], m_pivot=kwargs_cdm['m_pivot'], geometry_type='DOUBLE_CONE') self.geometry = Geometry(cosmo, zlens, zsource, kwargs_cdm['cone_opening_angle'], 'DOUBLE_CONE') self.lens_cosmo = LensCosmo(zlens, zsource, cosmo) self.kwargs_cdm = kwargs_cdm self.rendering_class = LineOfSight(kwargs_cdm, self.halo_mass_function, self.geometry, self.lens_cosmo, self.lens_plane_redshifts, self.delta_zs) self.logdelta_mass = 5. kwargs_delta = { 'zmin': zmin, 'zmax': zmax, 'log_mc': None, 'log_mlow': log_mlow, 'sigma_sub': sigma_sub, 'c_scale': None, 'c_power': None, 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'c_scatter_dex': 0.2, 'log_mhigh': log_mhigh, 'mdef_los': 'TNFW', 'host_m200': host_m200, 'LOS_normalization': LOS_normalization, 'draw_poisson': draw_poisson, 'subhalo_spatial_distribution': subhalo_spatial_distribution, 'log_mass_sheet_min': log_mass_sheet_min, 'log_mass_sheet_max': log_mass_sheet_max, 'kappa_scale': kappa_scale, 'power_law_index': power_law_index, 'delta_power_law_index': delta_power_law_index, 'delta_power_law_index_coupling': delta_power_law_index_coupling, 'm_pivot': m_pivot, 'logM': self.logdelta_mass, 'mass_fraction': 0.1, 'cone_opening_angle': cone_opening_angle, 'subhalo_mass_sheet_scale': 1., 'subhalo_convergence_correction_profile': 'NFW', 'r_tidal': '0.5Rs', 'mass_function_LOS_type': 'DELTA' } self.rendering_class_delta = LineOfSight( kwargs_delta, self.halo_mass_function, self.geometry, self.lens_cosmo, self.lens_plane_redshifts, self.delta_zs) def test_norm_slope(self): test_index = [10, 20] for i in test_index: z = self.lens_plane_redshifts[i] dz = self.delta_zs[i] norm, slope = self.rendering_class._normalization_slope(z, dz) slope_theory = self.halo_mass_function.plaw_index_z( z) + self.kwargs_cdm['delta_power_law_index'] norm_theory = self.halo_mass_function.norm_at_z_density( z, slope_theory, self.kwargs_cdm['m_pivot']) dv = self.geometry.volume_element_comoving(z, dz) norm_theory *= self.kwargs_cdm['LOS_normalization'] * dv npt.assert_almost_equal(slope, slope_theory) npt.assert_almost_equal(norm_theory, norm) def test_rendering(self): m = self.rendering_class.render_masses_at_z(0.7, 0.02) npt.assert_equal(True, len(m) > 0) x, y = self.rendering_class.render_positions_at_z(0.9, 10000) rmax = np.max(np.hypot(x, y)) rmax_theory = 0.5 * self.kwargs_cdm[ 'cone_opening_angle'] * self.geometry.rendering_scale(0.9) npt.assert_array_less(rmax, rmax_theory) x, y = self.rendering_class.render_positions_at_z(0.2, 0) npt.assert_equal(True, len(x) == 0) m, x, y, r3, redshifts, flag = self.rendering_class.render() npt.assert_equal(len(m), len(x)) npt.assert_equal(len(y), len(r3)) n = 0 for z in np.unique(redshifts): n += np.sum(redshifts == z) npt.assert_equal(True, n == len(m)) npt.assert_equal(True, len(self.realization_cdm.halos) == len(m)) def test_convergence_correction(self): idx = 20 z = self.lens_plane_redshifts[idx] dz = self.delta_zs[idx] log_mass_sheet_min = 8. # factor of two because the kappa sheets are added at every other lens plane norm, slope = self.rendering_class._normalization_slope(z, 2 * dz) mtheory = integrate_power_law_analytic( norm, 10**self.kwargs_cdm['log_mass_sheet_min'], 10**self.kwargs_cdm['log_mass_sheet_max'], 1., slope) mtheory_2 = integrate_power_law_analytic( norm, 10**log_mass_sheet_min, 10**self.kwargs_cdm['log_mass_sheet_max'], 1., slope) area = self.geometry.angle_to_physical_area( 0.5 * self.kwargs_cdm['cone_opening_angle'], z) kappa_theory = mtheory / self.lens_cosmo.sigma_crit_mass(z, area) kappa_theory_2 = mtheory_2 / self.lens_cosmo.sigma_crit_mass(z, area) kwargs_out, profile_names_out, redshifts = self.rendering_class.convergence_sheet_correction( ) kwargs_out_2, profile_names_out_2, redshifts_2 = self.rendering_class.\ convergence_sheet_correction({'log_mass_sheet_min': log_mass_sheet_min}) idx = np.where(redshifts == z)[0][0] kw = kwargs_out[idx] kw2 = kwargs_out_2[idx] name = profile_names_out[idx] npt.assert_equal(True, name == 'CONVERGENCE') kappa_generated = -kw['kappa'] kappa_generated_2 = -kw2['kappa'] npt.assert_almost_equal(kappa_theory, kappa_generated) npt.assert_almost_equal(kappa_theory_2, kappa_generated_2) npt.assert_equal(True, kw['kappa'] < 0.) def test_keys_convergence_sheets(self): keywords_out = self.rendering_class.keys_convergence_sheets( self.kwargs_cdm) required_keys = [ 'log_mass_sheet_min', 'log_mass_sheet_max', 'kappa_scale', 'zmin', 'zmax', 'delta_power_law_index' ] for x in required_keys: npt.assert_equal(x in keywords_out.keys(), True) def test_keys_rendering(self): keywords_out = self.rendering_class.keyword_parse_render( self.kwargs_cdm) required_keys = [ 'zmin', 'zmax', 'log_mc', 'log_mlow', 'log_mhigh', 'host_m200', 'LOS_normalization', 'draw_poisson', 'log_mass_sheet_min', 'log_mass_sheet_max', 'kappa_scale', 'a_wdm', 'b_wdm', 'c_wdm', 'delta_power_law_index', 'm_pivot' ] for x in required_keys: npt.assert_equal(x in keywords_out.keys(), True) kw_cdm = deepcopy(self.kwargs_cdm) kw_cdm['log_mc'] = None keywords_out = self.rendering_class.keyword_parse_render(kw_cdm) npt.assert_equal(keywords_out['a_wdm'] is None, True) npt.assert_equal(keywords_out['b_wdm'] is None, True) npt.assert_equal(keywords_out['c_wdm'] is None, True) def test_delta_function_rendering(self): m = self.rendering_class_delta.render_masses_at_z(0.5, 0.01) for mi in m: npt.assert_equal(np.log10(mi), self.logdelta_mass)
def setup(self): zlens, zsource = 0.4, 2. masses = [10**9.04, 10**8.2, 10**7.345, 10**7, 10**6.05, 10**7, 10**7] x = [0.5, 0.1, -0.9, -1.4, 1.2, 0., -1.] y = [0., 0.9, -1.4, -1., -0.4, 1., 0.9] redshifts = [0.1, 0.2, 0.3, zlens, zlens, 0.94, 0.94] subflags = [False, False, False, True, True, False, False] r3d = [100] * len(masses) mdefs_TNFW = ['TNFW'] * len(masses) # self.x = x self.y = y self.masses = masses self.redshifts = redshifts self.subflags = subflags self.r3d = r3d self.mdefs = mdefs_TNFW masses2 = [10**6.34, 10**9.2, 10**8.36] x2 = [1.5, 0.15, -1.9] y2 = [0.2, 0.3, -0.44] redshifts2 = [zlens, 0.4, 1.9] subflags2 = [True, False, False] r3d2 = [100] * len(masses2) profile_args_TNFW = { 'mc_model': 'diemer19', 'c_scatter': False, 'c_scatter_dex': 0.1 } cosmo = Cosmology() halo_mass_function = LensingMassFunction(cosmo, zlens, zsource, 10**6, 10**9, 6., m_pivot=10**8) self.halo_mass_function = halo_mass_function kwargs_cdm = { 'zmin': 0.01, 'zmax': 1.98, 'log_mc': None, 'log_mlow': 6., 'log_mhigh': 9., 'host_m200': 10**13, 'LOS_normalization': 2000., 'LOS_normalization_mass_sheet': 1., 'draw_poisson': False, 'log_mass_sheet_min': 7., 'log_mass_sheet_max': 10., 'kappa_scale': 1., 'delta_power_law_index': 0., 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'm_pivot': 10**8, 'cone_opening_angle': 6., 'mass_function_LOS_type': 'POWER_LAW' } kwargs_cdm_2 = { 'zmin': 0.01, 'zmax': 1.98, 'log_mc': None, 'log_mlow': 6., 'log_mhigh': 9., 'host_m200': 10**13, 'LOS_normalization': 2000., 'LOS_normalization_mass_sheet': 1., 'draw_poisson': False, 'log_mass_sheet_min': 7., 'log_mass_sheet_max': 10., 'kappa_scale': 1., 'delta_power_law_index': 0., 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'm_pivot': 10**8, 'cone_opening_angle': 6., 'subtract_exact_mass_sheets': True, 'mass_function_LOS_type': 'POWER_LAW' } kwargs_cdm.update(profile_args_TNFW) self.kwargs_cdm = kwargs_cdm self.kwargs_cdm_2 = kwargs_cdm_2 lens_plane_redshifts = np.append(np.arange(0.01, 0.5, 0.02), np.arange(0.5, 1.5, 0.02)) delta_zs = [] for i in range(0, len(lens_plane_redshifts) - 1): delta_zs.append(lens_plane_redshifts[i + 1] - lens_plane_redshifts[i]) delta_zs.append(1.5 - lens_plane_redshifts[-1]) geometry = Geometry(cosmo, 0.5, 1.5, 6., 'DOUBLE_CONE') lens_cosmo = LensCosmo(zlens, zsource, cosmo) self.lens_cosmo = lens_cosmo halo_population = HaloPopulation(['LINE_OF_SIGHT'], self.kwargs_cdm, lens_cosmo, geometry, halo_mass_function, lens_plane_redshifts, delta_zs) self.rendering_classes = halo_population.rendering_classes mdef = ['NFW'] * len(masses) self.realization_cdm = Realization( masses, x, y, r3d, mdef, redshifts, subflags, lens_cosmo, halos=None, kwargs_realization=self.kwargs_cdm_2, mass_sheet_correction=True, rendering_classes=self.rendering_classes, geometry=geometry) mdef = ['PT_MASS'] * len(masses) self.realization_cdm2 = Realization( masses2, x2, y2, r3d2, mdef, redshifts2, subflags2, lens_cosmo, halos=None, kwargs_realization=self.kwargs_cdm, mass_sheet_correction=True, rendering_classes=self.rendering_classes, geometry=geometry) mdef = ['PJAFFE'] * len(masses) self.realization_cdm3 = Realization( masses2, x2, y2, r3d2, mdef, redshifts2, subflags2, lens_cosmo, halos=None, kwargs_realization=self.kwargs_cdm, mass_sheet_correction=True, rendering_classes=self.rendering_classes, geometry=geometry) self.halos_cdm = self.realization_cdm.halos halo_tags = [] for halo in self.realization_cdm.halos: halo_tags.append(halo.unique_tag) self.halo_tags = halo_tags halo_tags = [] for halo in self.realization_cdm2.halos: halo_tags.append(halo.unique_tag) self.halo_tags2 = halo_tags self.real_1_data = [x, y, masses, redshifts, subflags, redshifts] self.real_2_data = [x2, y2, masses2, redshifts2, subflags2, redshifts2]
def setup(self): mass = 10**8. x = 0.5 y = 1. r3d = np.sqrt(1 + 0.5**2 + 70**2) self.r3d = r3d mdef = 'TNFW' self.z = 0.25 sub_flag = True self.H0 = 70 self.omega_baryon = 0.03 self.omega_DM = 0.25 self.sigma8 = 0.82 curvature = 'flat' self.ns = 0.9608 cosmo_params = { 'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon, 'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature } self._dm, self._bar = self.omega_DM, self.omega_baryon cosmo = Cosmology(cosmo_kwargs=cosmo_params) self.lens_cosmo = LensCosmo(self.z, 2., cosmo) kwargs_suppression = {'a_mc': 0.5, 'b_mc': 1.9} suppression_model = 'hyperbolic' profile_args = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': None, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'c_scatter': False, 'c_scatter_dex': 0.1, 'mc_mdef': '200c' } self.profile_args_WDM = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': 7.6, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'mc_model': 'diemer19', 'LOS_truncation_factor': 40, 'c_scatter': False, 'c_scatter_dex': 0.1, 'mc_mdef': '200c' } self._profile_args = profile_args self.mass_subhalo = mass self.subhalo = TNFWSubhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self.subhalo_WDM = TNFWSubhalo(mass, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_WDM, unique_tag=np.random.rand()) mass_field_halo = 10**7. sub_flag = False self.mass_field_halo = mass_field_halo self.field_halo = TNFWFieldHalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, profile_args, unique_tag=np.random.rand()) self.field_halo_WDM = TNFWFieldHalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_WDM, unique_tag=np.random.rand()) self.profile_args_custom = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': None, 'c_scatter': False, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'mc_model': { 'custom': True, 'c0': 6., 'beta': 0.2, 'zeta': -0.3 }, 'LOS_truncation_factor': 40, 'c_scatter_dex': 0.1, 'mc_mdef': '200c' } mdef = 'TNFW' sub_flag = False self.field_halo_custom = TNFWFieldHalo(self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_custom, unique_tag=np.random.rand()) sub_flag = True self.subhalo_custom = TNFWSubhalo(self.mass_subhalo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_custom, unique_tag=np.random.rand()) self.profile_args_WDM_custom = { 'RocheNorm': 1.2, 'RocheNu': 2 / 3, 'evaluate_mc_at_zlens': True, 'log_mc': 8., 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'c_scatter': False, 'mc_model': { 'custom': True, 'c0': 6., 'beta': 0.2, 'zeta': -0.3 }, 'LOS_truncation_factor': 40, 'c_scatter_dex': 0.1, 'mc_mdef': '200c' } sub_flag = True self.subhalo_custom_WDM = TNFWSubhalo(self.mass_subhalo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_WDM_custom, unique_tag=np.random.rand()) sub_flag = False self.field_halo_custom_WDM = TNFWFieldHalo( self.mass_field_halo, x, y, r3d, mdef, self.z, sub_flag, self.lens_cosmo, self.profile_args_WDM_custom, unique_tag=np.random.rand())
def setup(self): cosmo = Cosmology() self.cosmo = cosmo self.lenscosmo = LensCosmo(0.5, 1.5, cosmo) self.concentration = Concentration(self.lenscosmo)
def setup(self): zlens, zsource = 0.5, 2. zmin = 0.01 zmax = 1.98 log_mlow = 6. log_mhigh = 9. host_m200 = 10**13 LOS_normalization = 100. draw_poisson = False log_mass_sheet_min = 7. log_mass_sheet_max = 10. kappa_scale = 1. delta_power_law_index = -0.17 delta_power_law_index_coupling = 0.7 cone_opening_angle = 6. m_pivot = 10**8 sigma_sub = 0.6 power_law_index = -1.8 subhalo_spatial_distribution = 'HOST_NFW' kwargs_cdm = { 'zmin': zmin, 'zmax': zmax, 'log_mc': None, 'log_mlow': log_mlow, 'sigma_sub': sigma_sub, 'c_scale': None, 'c_power': None, 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'c_scatter_dex': 0.2, 'log_mhigh': log_mhigh, 'host_m200': host_m200, 'LOS_normalization': LOS_normalization, 'draw_poisson': draw_poisson, 'subhalo_spatial_distribution': subhalo_spatial_distribution, 'log_mass_sheet_min': log_mass_sheet_min, 'log_mass_sheet_max': log_mass_sheet_max, 'kappa_scale': kappa_scale, 'power_law_index': power_law_index, 'delta_power_law_index': delta_power_law_index, 'delta_power_law_index_coupling': delta_power_law_index_coupling, 'm_pivot': m_pivot, 'cone_opening_angle': cone_opening_angle, 'subhalo_mass_sheet_scale': 1., 'subhalo_convergence_correction_profile': 'NFW', 'r_tidal': '0.5Rs', 'mdef_subs': 'TNFW', 'mdef_los': 'TNFW' } kwargs_wdm = deepcopy(kwargs_cdm) log_mc = 7.1 a_wdm = 1. b_wdm = 0.8 c_wdm = -1.3 kwargs_wdm['log_mc'] = log_mc kwargs_wdm['a_wdm'] = a_wdm kwargs_wdm['b_wdm'] = b_wdm kwargs_wdm['c_wdm'] = c_wdm kwargs_wdm['c_scale'] = 60. kwargs_wdm['c_power'] = -0.17 pyhalo = pyHalo(zlens, zsource) lens_plane_redshifts, delta_zs = pyhalo.lens_plane_redshifts( kwargs_cdm) cosmo = Cosmology() self.lens_plane_redshifts = lens_plane_redshifts self.delta_zs = delta_zs self.halo_mass_function = LensingMassFunction( cosmo, zlens, zsource, kwargs_cdm['log_mlow'], kwargs_cdm['log_mhigh'], kwargs_cdm['cone_opening_angle'], m_pivot=kwargs_cdm['m_pivot'], geometry_type='DOUBLE_CONE', use_lookup_table=True) self.geometry = Geometry(cosmo, zlens, zsource, kwargs_cdm['cone_opening_angle'], 'DOUBLE_CONE') self.lens_cosmo = LensCosmo(zlens, zsource, cosmo) self.kwargs_cdm = kwargs_cdm self.kwargs_wdm = kwargs_wdm pyhalo = pyHalo(zlens, zsource) model_list_field = ['LINE_OF_SIGHT'] model_list_sub = ['SUBHALOS'] self.realization_cdm = pyhalo.render(model_list_sub + model_list_field, kwargs_cdm)[0] self.realization_cdm_field = pyhalo.render(model_list_field, kwargs_cdm)[0] self.realization_wdm_field = pyhalo.render(model_list_field, kwargs_wdm)[0] self.realization_wdm_subhalos = pyhalo.render(model_list_sub, kwargs_wdm)[0]
def setup(self): zlens, zsource = 0.5, 2. zmin = 0.01 zmax = 1.98 log_mlow = 6. log_mhigh = 9. host_m200 = 10**13 LOS_normalization = 1. draw_poisson = False log_mass_sheet_min = 7. log_mass_sheet_max = 10. kappa_scale = 1. delta_power_law_index = -0.17 delta_power_law_index_coupling = 0.5 cone_opening_angle = 6. m_pivot = 10**8 sigma_sub = 0.1 power_law_index = -1.9 subhalo_spatial_distribution = 'HOST_NFW' kwargs_suppression = {'c_scale': 10.5, 'c_power': -0.2} suppression_model = 'polynomial' kwargs_cdm = { 'zmin': zmin, 'zmax': zmax, 'log_mc': None, 'log_mlow': log_mlow, 'sigma_sub': sigma_sub, 'kwargs_suppression': kwargs_suppression, 'suppression_model': suppression_model, 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'c_scatter_dex': 0.2, 'log_mhigh': log_mhigh, 'host_m200': host_m200, 'LOS_normalization': LOS_normalization, 'draw_poisson': draw_poisson, 'subhalo_spatial_distribution': subhalo_spatial_distribution, 'log_mass_sheet_min': log_mass_sheet_min, 'log_mass_sheet_max': log_mass_sheet_max, 'kappa_scale': kappa_scale, 'power_law_index': power_law_index, 'delta_power_law_index': delta_power_law_index, 'delta_power_law_index_coupling': delta_power_law_index_coupling, 'm_pivot': m_pivot, 'cone_opening_angle': cone_opening_angle, 'subhalo_mass_sheet_scale': 1., 'subhalo_convergence_correction_profile': 'NFW', 'r_tidal': '0.5Rs', 'mass_function_LOS_type': 'POWER_LAW' } kwargs_wdm = deepcopy(kwargs_cdm) log_mc = 7.3 a_wdm = 0.8 b_wdm = 1.1 c_wdm = -1.2 kwargs_wdm['log_mc'] = log_mc kwargs_wdm['a_wdm'] = a_wdm kwargs_wdm['b_wdm'] = b_wdm kwargs_wdm['c_wdm'] = c_wdm kwargs_wdm['kwargs_suppression'] = kwargs_suppression kwargs_wdm['suppression_model'] = suppression_model kwargs_no_sheet = deepcopy(kwargs_cdm) kwargs_no_sheet['mass_function_LOS_type'] = 'DELTA' kwargs_no_sheet['mass_fraction'] = 0.1 kwargs_no_sheet['logM'] = 6. lens_plane_redshifts = np.append(np.arange(0.01, 0.5, 0.02), np.arange(0.5, 1.5, 0.02)) delta_zs = [] for i in range(0, len(lens_plane_redshifts) - 1): delta_zs.append(lens_plane_redshifts[i + 1] - lens_plane_redshifts[i]) delta_zs.append(1.5 - lens_plane_redshifts[-1]) cosmo = Cosmology() self.lens_plane_redshifts = lens_plane_redshifts self.delta_zs = delta_zs self.halo_mass_function = LensingMassFunction( cosmo, 0.5, 1.5, kwargs_cdm['log_mlow'], kwargs_cdm['log_mhigh'], 6., m_pivot=kwargs_cdm['m_pivot'], geometry_type='DOUBLE_CONE') self.geometry = Geometry(cosmo, 0.5, 1.5, 6., 'DOUBLE_CONE') self.lens_cosmo = LensCosmo(zlens, zsource, cosmo) self.kwargs_cdm = kwargs_cdm self.kwargs_wdm = kwargs_wdm self.kwargs_no_sheet = kwargs_no_sheet
class TestLensCosmo(object): def setup(self): kwargs_cosmo = {'Om0': 0.2} self.cosmo = Cosmology(cosmo_kwargs=kwargs_cosmo) zlens, zsource = 0.3, 1.7 self.lens_cosmo = LensCosmo(zlens, zsource, self.cosmo) self.h = self.cosmo.h self.con = Concentration(self.lens_cosmo) self._colossus_nfw = NFWProfile def test_const(self): D_ds = self.cosmo.D_A(0.3, 1.7) D_d = self.cosmo.D_A_z(0.3) D_s = self.cosmo.D_A_z(1.7) c_Mpc_sec = un.Quantity(c, unit=un.Mpc / un.s) G_Mpc3_Msun_sec2 = un.Quantity(G, unit=un.Mpc ** 3 / un.s ** 2 / un.solMass) const = c_Mpc_sec ** 2 / (4 * np.pi * G_Mpc3_Msun_sec2) sigma_crit_mpc = const.value * D_s / (D_d * D_ds) sigma_crit_kpc = sigma_crit_mpc * 1000 ** -2 npt.assert_almost_equal(self.lens_cosmo.sigma_crit_lensing/sigma_crit_mpc, 1, 4) npt.assert_almost_equal(self.lens_cosmo.sigma_crit_lens_kpc/sigma_crit_kpc, 1, 4) def test_sigma_crit_mass(self): area = 2. sigma_crit_mass = self.lens_cosmo.sigma_crit_mass(0.7, area) sigma_crit = self.lens_cosmo.get_sigma_crit_lensing(0.7, 1.7) npt.assert_almost_equal(sigma_crit_mass, sigma_crit * area) def test_colossus(self): colossus = self.lens_cosmo.colossus npt.assert_almost_equal(colossus.Om0, 0.2) def test_truncate_roche(self): m = 10**9. norm = 1.4 power = 0.9 r3d = 1000 rt = norm * (m / 10 ** 7) ** (1./3) * (r3d / 50) ** power rtrunc = self.lens_cosmo.truncation_roche(m, r3d, norm, power) npt.assert_almost_equal(rt, rtrunc, 3) def test_LOS_trunc(self): rt = self.lens_cosmo.LOS_truncation_rN(10**8, 0.2, 90) rtrunc = self.lens_cosmo.rN_M_nfw_comoving(10**8 * self.lens_cosmo.cosmo.h, 90, 0.2) npt.assert_almost_equal(rt, 1000 * rtrunc * (1+0.2)**-1 / self.lens_cosmo.cosmo.h) def test_NFW_concentration(self): c = self.lens_cosmo.NFW_concentration(10 ** 9, 0.2, model='diemer19', scatter=False) c2 = self.lens_cosmo.NFW_concentration(10 ** 9, 0.2, model='diemer19', scatter=True) npt.assert_raises(AssertionError, npt.assert_array_equal, c, c2) logmhm = 8. kwargs_suppression, suppression_model = {'c_scale': 60., 'c_power': -0.17}, 'polynomial' c_wdm = self.lens_cosmo.NFW_concentration(10 ** 9, 0.2, model='diemer19', scatter=False, logmhm=logmhm, kwargs_suppresion=kwargs_suppression, suppression_model=suppression_model) suppresion = WDM_concentration_suppresion_factor(10**9, 0.2, logmhm, suppression_model, kwargs_suppression) npt.assert_almost_equal(suppresion * c, c_wdm) kwargs_suppression, suppression_model = {'a_mc': 0.5, 'b_mc': 0.17}, 'hyperbolic' c_wdm = self.lens_cosmo.NFW_concentration(10 ** 9, 0.2, model='diemer19', scatter=False, logmhm=logmhm, kwargs_suppresion=kwargs_suppression, suppression_model=suppression_model) suppresion = WDM_concentration_suppresion_factor(10 ** 9, 0.2, logmhm, suppression_model, kwargs_suppression) npt.assert_almost_equal(suppresion * c, c_wdm) def test_subhalo_accretion(self): zi = [self.lens_cosmo.z_accreted_from_zlens(10**8, 0.5) for _ in range(0, 20000)] h, b = np.histogram(zi, bins=np.linspace(0.5, 6, 20)) # number at the lens redshift should be about 5x that at redshift 4 ratio = h[0]/h[12] npt.assert_almost_equal(ratio/5 - 1, 0., 1) def test_nfw_fundamental_parameters(self): for z in [0., 0.74, 1.2]: M, c = 10**8, 17.5 rho_crit_z = self.cosmo.rho_crit(z) rhos, rs, r200 = self.lens_cosmo.nfwParam_physical_Mpc(M, c, z) h = self.cosmo.h _rhos, _rs = self._colossus_nfw.fundamentalParameters(M * h, c, z, '200c') # output in units (M h^2 / kpc^2, kpc/h) rhos_col = _rhos * h ** 2 * 1000 ** 3 rs_col = _rs / h / 1000 r200_col = rs * c npt.assert_almost_equal(rhos/rhos_col, 1, 3) npt.assert_almost_equal(rs/rs_col, 1, 3) npt.assert_almost_equal(r200/r200_col, 1, 3) def _profile(x): fac = x * (1 + x) ** 2 return 1. / fac def _integrand(x): return 4 * np.pi * x ** 2 * _profile(x) volume = 4 * np.pi/3 * r200 ** 3 integral = quad(_integrand, 0, r200/rs)[0] mean_density = rhos * rs ** 3 * integral / volume ratio = mean_density/rho_crit_z npt.assert_almost_equal(ratio/200, 1., 3) def test_mhm_convert(self): mthermal = 5.3 mhm = self.lens_cosmo.mthermal_to_halfmode(mthermal) mthermal_out = self.lens_cosmo.halfmode_to_thermal(mhm) npt.assert_almost_equal(mthermal/mthermal_out, 1, 2) fsl = self.lens_cosmo.mhm_to_fsl(10**8.) npt.assert_array_less(fsl, 100) def test_NFW_phys2angle(self): c = self.lens_cosmo.NFW_concentration(10**8, 0.5, scatter=False) out = self.lens_cosmo.nfw_physical2angle(10**8, c, 0.5) out2 = self.lens_cosmo.nfw_physical2angle_fromM(10**8, 0.5) for (x, y) in zip(out, out2): npt.assert_almost_equal(x, y) rhos_kpc, rs_kpc, _ = self.lens_cosmo.NFW_params_physical(10**8, c, 0.5) rhos_mpc = rhos_kpc * 1000 ** 3 rs_mpc = rs_kpc * 1e-3 rs, theta_rs = self.lens_cosmo.nfw_physical2angle_fromNFWparams(rhos_mpc, rs_mpc, 0.5) npt.assert_almost_equal(rs, out[0]) npt.assert_almost_equal(theta_rs, out[1])