Source code for skypy.halos.abundance_matching
"""Abundance matching module.
This module provides methods to perform abundance matching between catalogs of
galaxies and dark matter halos.
Models
======
.. autosummary::
:nosignatures:
:toctree: ../api/
vale_ostriker
"""
import numpy as np
from skypy.halos.mass import press_schechter, number_subhalos, subhalo_mass_sampler
from skypy.galaxies.luminosity import schechter_lf_magnitude
__all__ = [
'vale_ostriker',
]
[docs]def vale_ostriker(halo_kwargs, subhalo_kwargs, galaxy_kwargs, cosmology):
"""Vale & Ostriker abundance matching.
Generate matched arrays of (sub)halos masses and galaxy absolute magnitudes
following the abundance matching model in [1]_.
Parameters
----------
halo_kwargs : dict
Dictionary of keyword arguments for `~skypy.halos.mass.press_schechter`.
subhalo_kwargs : dict
Dictionary of keyword arguments for `~skypy.halos.mass.number_subhalos`
and `~skypy.halos.mass.subhalo_mass_sampler`.
galaxy_kwargs : dict
Dictionary of keyword arguments for
`~skypy.galaxies.luminosity.schechter_lf_magnitude`.
cosmology : astropy.cosmology.Cosmology
Cosmology argument for `~skypy.halos.mass.press_schechter` and
`~skypy.galaxies.luminosity.schechter_lf_magnitude`.
Returns
-------
mass : array_like
Array of (sub)halo masses in units of solar masses.
group : array_like
Array of halo group ID numbers.
parent : array_like
Array of boolean values indicating if the halo is a parent.
magnitude : array_like
Array of galaxy absolute magnitudes.
References
----------
.. [1] Vale A., Ostriker J. P., 2004, MNRAS, 353, 189
"""
# Sample halo and subhalo masses
halo_mass = press_schechter(**halo_kwargs, cosmology=cosmology)
halo_mass[::-1].sort() # Sort in-place from high to low for indexing
n_subhalos = number_subhalos(halo_mass, **subhalo_kwargs)
sampler_kwargs = {k: v for k, v in subhalo_kwargs.items() if k not in ['gamma_M', 'noise']}
subhalo_mass = subhalo_mass_sampler(halo_mass, n_subhalos, **sampler_kwargs)
# Assign subhalos to groups with their parent halos
n_halos = len(halo_mass)
halo_group = np.arange(n_halos)
indexing = np.zeros(n_halos + 1, dtype=int)
indexing[1:] = np.cumsum(n_subhalos)
total_subhalos = indexing[-1]
subhalo_group = np.empty(total_subhalos, dtype=int)
for first, last, id in zip(indexing[:-1], indexing[1:], halo_group):
subhalo_group[first:last] = id
# Concatenate halos and subhalos
mass = np.concatenate([halo_mass, subhalo_mass])
group = np.concatenate([halo_group, subhalo_group])
parent = np.empty(n_halos+total_subhalos, dtype=bool)
parent[:n_halos] = True
parent[n_halos:] = False
# Sample galaxy magnitudes
magnitude = schechter_lf_magnitude(**galaxy_kwargs, cosmology=cosmology)
n_galaxies = len(magnitude)
# Sort halos and galaxies by mass and magnitude
n_matches = min(n_halos + total_subhalos, n_galaxies)
sort_mass = np.argsort(mass)[-n_matches:][::-1]
sort_magnitudes = np.argsort(magnitude)[:n_matches]
mass = mass[sort_mass]
group = group[sort_mass]
parent = parent[sort_mass]
magnitude = magnitude[sort_magnitudes]
return mass, group, parent, magnitude