def test_nfw_mc_positions():
    """
  Compares samples with halotools and analytic density
  """
    model = NFWProfile()
    scaled_radius = np.logspace(-2, 0, 100)

    for c in [5, 10, 20]:
        distr = NFW(concentration=c, Rvir=1)

        samples = model.mc_generate_nfw_radial_positions(num_pts=int(1e6),
                                                         conc=c,
                                                         halo_radius=1)
        samples_tf = distr.sample(1e6)

        h = np.histogram(samples, 32, density=True, range=[0.01, 1])
        h_tf = np.histogram(samples_tf, 32, density=True, range=[0.01, 1])
        x = 0.5 * (h[1][:-1] + h[1][1:])

        p = distr.prob(x)

        # Comparing histograms
        assert_allclose(h[0], h_tf[0], rtol=5e-2)
        # Comparing to prob
        assert_allclose(h_tf[0], p, rtol=5e-2)
def test_nfw_mass_cdf():
    """
  Compares CDF values to halotools
  """
    model = NFWProfile()
    scaled_radius = np.logspace(-2, 0, 100)

    for c in [5, 10, 20]:
        distr = NFW(concentration=c, Rvir=1)
        y = model.cumulative_mass_PDF(scaled_radius, conc=c)
        y_tf = distr.cdf(scaled_radius)
        assert_allclose(y, y_tf.numpy(), rtol=1e-4)
Ejemplo n.º 3
0
    def _dc_fog_corr(
        self,
        abs_mag,
        halos,
        galinhalo,
        halo_centers,
        mag_threshold=-20.5,
        seedvalue=None,
    ):
        """Corrected comoving distance."""
        # array to store return results

        dcfogcorr = np.zeros(len(self.z))

        # run for each massive halo
        for i in halos.labels_h_massive[0]:
            # select only galaxies with magnitudes over than -20.5
            sat_gal_mask = (galinhalo.groups == i) * (abs_mag > mag_threshold)

            # number of galaxies for corrections
            numgal = np.sum(sat_gal_mask)

            # Monte Carlo simulation for distance
            nfw = NFWProfile(self.cosmo, halo_centers[i], mdef=self.delta_c)
            radial_positions_pos = nfw.mc_generate_nfw_radial_positions(
                num_pts=N_MONTE_CARLO,
                halo_radius=halos.radius[i],
                seed=seedvalue,
            )
            radial_positions_neg = nfw.mc_generate_nfw_radial_positions(
                num_pts=N_MONTE_CARLO,
                halo_radius=halos.radius[i],
                seed=seedvalue,
            )
            radial_positions_neg = -1 * radial_positions_neg
            radial_positions = np.r_[radial_positions_pos,
                                     radial_positions_neg]

            # random choice of distance for each galaxy
            al = np.random.RandomState(seedvalue)
            dc = al.choice(radial_positions, size=numgal)

            # combine Monte Carlo distance and distance to halo center
            dcfogcorr[sat_gal_mask] = halo_centers[i] + dc

        return dcfogcorr, halo_centers, halos.radius, galinhalo.groups
Ejemplo n.º 4
0
def HaloConcentration(mass, cosmo, redshift, mdef='vir'):
    """
    Return halo concentration from halo mass, based on the analytic fitting
    formulas presented in
    `Dutton and Maccio 2014 <https://arxiv.org/abs/1402.7073>`_.

    .. note::
        The units of the input mass are assumed to be :math:`M_{\odot}/h`

    Parameters
    ----------
    mass : array_like
        either a numpy or dask array specifying the halo mass; units
        assumed to be :math:`M_{\odot}/h`
    cosmo : :class:`~nbodykit.cosmology.cosmology.Cosmology`
        the cosmology instance used in the analytic formula
    redshift : float
        compute the c(M) relation at this redshift
    mdef : str, optional
        string specifying the halo mass definition to use; should be
        'vir' or 'XXXc' or 'XXXm' where 'XXX' is an int specifying the
        overdensity

    Returns
    -------
    concen : :class:`dask.array.Array`
        a dask array holding the analytic concentration values

    References
    ----------
    Dutton and Maccio, "Cold dark matter haloes in the Planck era: evolution
    of structural parameters for Einasto and NFW profiles", 2014, arxiv:1402.7073
    """
    from halotools.empirical_models import NFWProfile

    if not isinstance(mass, da.Array):
        mass = da.from_array(mass, chunks=100000)

    # initialize the model
    kws = {'cosmology':cosmo.to_astropy(), 'conc_mass_model':'dutton_maccio14', 'mdef':mdef, 'redshift':redshift}
    model = NFWProfile(**kws)

    return mass.map_blocks(lambda mass: model.conc_NFWmodel(prim_haloprop=mass), dtype=mass.dtype)
Ejemplo n.º 5
0
    def _group_prop(self, id_groups, groups, xyz):
        """Determine halos properties.

        Calculate Cartesian coordinates of halo centers, the halos comoving
        distances, the z-values of halo centers, halos radii and halos masses.

        """
        # select only galaxies in groups
        galincluster = id_groups[id_groups > -1]

        # arrays to store results
        xyzcenters = np.empty([len(galincluster), 3])
        dc_center = np.empty([len(galincluster)])
        hmass = np.empty([len(galincluster)])
        z_center = np.empty([len(galincluster)])
        radius = np.empty([len(galincluster)])

        # run for each group of galaxies
        for i in galincluster:
            mask = groups == i

            # halo radius
            radius[i] = self._radius(self.ra[mask], self.dec[mask],
                                     self.z[mask])

            # halo center
            x, y, z, dc, z_cen = self._centers(xyz[mask], self.z[mask])
            xyzcenters[i, 0] = x
            xyzcenters[i, 1] = y
            xyzcenters[i, 2] = z
            dc_center[i] = dc
            z_center[i] = z_cen

            # halo mass
            # use a Navarro profile (Navarro et al. 1997) [navarro97]_
            model = NFWProfile(self.cosmo, z_cen, mdef=self.delta_c)
            hmass[i] = model.halo_radius_to_halo_mass(radius[i])
        return xyzcenters, dc_center, z_center, radius, hmass
Ejemplo n.º 6
0
import halotools
from halotools.empirical_models import NFWProfile
cosmo
_critical_density_func = None


def rho0(z):
    global _rho0_func
    if _critical_density_func is None:
        zs = np.linspace(0, 10, 1000)
        rho_0 = 2.77536627e11
        density = cosmo.critical_density(zs) / cosmo.critical_density0 * rho_0
        _critical_density_func = np.interp(z, density)


nfwprofile = NFWProfile()


def F_grav(R, M200, c):
    return dtk.NFW_enclosed_mass(R, c) * M200 / R**2


def F_tidal(r, R, M200, c):
    return -F_grav(R, M200, c) + F_grav(R - r, M200, c)


plt.figure()
r = np.linspace(0, 0.2, 1000)
R = 1
M1 = 1e14
M2 = 1e11
Ejemplo n.º 7
0
def plot_richness_mass_relation():
    background.set_cosmology("wmap7")
    richness = np.logspace(np.log10(20), np.log10(300), 100)
    m200m_rykoff, r200m_rykoff = background.lambda_to_m200_r200(
        richness, 0.25, richness_mass_author="Rykoff_mean")
    m200m_simet, r200m_simet = background.lambda_to_m200_r200(
        richness, 0.25, richness_mass_author="Simet_mean")
    m200m_baxter, r200m_baxter = background.lambda_to_m200_r200(
        richness, 0.25, richness_mass_author="Baxter_mean")
    m200c_rykoff, r200c_rykoff = background.lambda_to_m200_r200(
        richness, 0.25, richness_mass_author="Rykoff_crit")
    m200c_simet, r200c_simet = background.lambda_to_m200_r200(
        richness, 0.25, richness_mass_author="Simet_crit")
    m200c_baxter, r200c_baxter = background.lambda_to_m200_r200(
        richness, 0.25, richness_mass_author="Baxter_crit")
    plt.figure()
    plt.plot(richness, m200m_rykoff, '-r')
    plt.plot(richness, m200m_simet, '-b')
    plt.plot(richness, m200m_baxter, '-g')
    plt.plot(richness, m200c_rykoff, '--r')
    plt.plot(richness, m200c_simet, '--b')
    plt.plot(richness, m200c_baxter, '--g')
    plt.plot([], [], 'r', label='rykoff')
    plt.plot([], [], 'b', label='simet')
    plt.plot([], [], 'g', label='baxter')
    plt.plot([], [], '-k', label='M200m')
    plt.plot([], [], '--k', label='M200c')
    plt.legend(loc='best', framealpha=0.3)
    plt.yscale('log')
    plt.xscale('log')
    plt.xlabel('Richness')
    plt.ylabel(r'M$_{200}$')
    plt.grid()

    plt.figure()
    plt.plot(richness, r200m_rykoff, '-r')
    plt.plot(richness, r200m_simet, '-b')
    plt.plot(richness, r200m_baxter, '-g')
    plt.plot(richness, r200c_rykoff, '--r')
    plt.plot(richness, r200c_simet, '--b')
    plt.plot(richness, r200c_baxter, '--g')
    plt.plot([], [], 'r', label='rykoff')
    plt.plot([], [], 'b', label='simet')
    plt.plot([], [], 'g', label='baxter')
    plt.plot([], [], '-k', label='R200m')
    plt.plot([], [], '--k', label='R200c')
    plt.legend(loc='best', framealpha=0.3)
    plt.yscale('log')
    plt.xscale('log')
    plt.xlabel('Richness')
    plt.ylabel(r'R$_{200}$')
    plt.grid()

    plt.figure()
    plt.plot(richness, m200c_rykoff / m200m_rykoff, '-r', label='rykoff')
    plt.plot(richness, m200c_simet / m200m_simet, '-b', label='simet')
    plt.plot(richness, m200c_baxter / m200m_baxter, '-g', label='baxter')
    plt.legend(loc='best', framealpha=0.3)
    plt.xscale('log')
    plt.xlabel('Richness')
    plt.ylabel(r'M200c/M200m')
    plt.grid()

    plt.figure()
    plt.plot(richness, r200c_rykoff / r200m_rykoff, '-r', label='rykoff')
    plt.plot(richness, r200c_simet / r200m_simet, '-b', label='simet')
    plt.plot(richness, r200c_baxter / r200m_baxter, '-g', label='baxter')
    plt.legend(loc='best', framealpha=0.3)
    plt.xscale('log')
    plt.xlabel('Richness')
    plt.ylabel(r'R200c/R200m')
    plt.grid()

    plt.figure()
    a = 1.0 / (1.0 + 0.25)
    # plt.plot(m200m_simet, r200m_simet, '-b',  label='my simet mean')
    # plt.plot(m200c_simet, r200c_simet, '--b', label='my simet crit')
    plt.plot(m200m_simet, r200m_simet, '-b', label='my simet mean')
    plt.plot(m200c_simet, r200c_simet, '--b', label='my simet crit')

    nfw_200m = NFWProfile(mdef='200m', redshift=0.25)
    nfw_200c = NFWProfile(mdef='200c', redshift=0.25)
    plt.plot(m200m_simet,
             nfw_200m.halo_mass_to_halo_radius(m200m_simet) * 1000,
             '-r',
             label='ht simet mean')
    plt.plot(m200c_simet,
             nfw_200c.halo_mass_to_halo_radius(m200c_simet) * 1000,
             '--r',
             label='ht simet crit')

    plt.plot(m200m_simet,
             M_to_R(m200m_simet, 0.25, '200m'),
             '-g',
             label='cls simet mean')
    plt.plot(m200c_simet,
             M_to_R(m200c_simet, 0.25, '200c'),
             '--g',
             label='cls simet crit')

    plt.legend(loc='best', framealpha=0.3)
    plt.xscale('log')
    plt.yscale('log')
    plt.xlabel('M200 [Msun]')
    plt.ylabel('R200 [proper kpc]')
    plt.grid()

    plt.show()

    #header list can be found in http://arxiv.org/pdf/1303.3562v2.pdf
    hdulist = pyfits.open("redmapper_dr8_public_v6.3_catalog.fits")
    tdata = hdulist[1].data

    # red_ra = tdata.field('ra')
    # red_dec= tdata.field('dec')
    red_z = tdata.field('z_lambda')
    red_lambda = tdata.field('lambda')
    # red_pcen=tdata.field('p_cen')

    plt.figure()
    h, xbins = np.histogram(red_lambda, bins=256)
    plt.plot(dtk.bins_avg(xbins), h)
    plt.yscale('log')
    plt.xscale('log')
    plt.xlabel('Richness')
    plt.ylabel('count')

    m200m_rykoff = background.lambda_to_m200m_Rykoff(red_lambda, 0.25)
    m200m_simet = background.lambda_to_m200m_Simet(red_lambda, 0.25)
    m200m_baxter = background.lambda_to_m200m_Baxter(red_lambda, 0.25)
    m200c_rykoff = background.lambda_to_m200c_Rykoff(red_lambda, 0.25)
    m200c_simet = background.lambda_to_m200c_Simet(red_lambda, 0.25)
    m200c_baxter = background.lambda_to_m200c_Baxter(red_lambda, 0.25)

    xbins = np.logspace(13.5, 15.5, 100)
    xbins_avg = dtk.bins_avg(xbins)

    plt.figure()
    h, _ = np.histogram(m200m_rykoff, bins=xbins)
    plt.plot(xbins_avg, h, label='rykoff')
    h, _ = np.histogram(m200m_simet, bins=xbins)
    plt.plot(xbins_avg, h, label='simet')
    h, _ = np.histogram(m200m_baxter, bins=xbins)
    plt.plot(xbins_avg, h, label='baxter')
    plt.yscale('log')
    plt.xscale('log')
    plt.ylabel('Counts')
    plt.xlabel('M$_{200m}$ [h$^{-1}$ M$_\odot$]')
    plt.legend(loc='best', framealpha=1.0)
    plt.grid()

    plt.figure()
    h, _ = np.histogram(m200c_rykoff, bins=xbins)
    plt.plot(xbins_avg, h, label='rykoff')
    h, _ = np.histogram(m200c_simet, bins=xbins)
    plt.plot(xbins_avg, h, label='simet')
    h, _ = np.histogram(m200c_baxter, bins=xbins)
    plt.plot(xbins_avg, h, label='baxter')
    plt.yscale('log')
    plt.xscale('log')
    plt.ylabel('Counts')
    plt.xlabel('M$_{200c}$ [h$^{-1}$ M$_\odot$]')
    plt.legend(loc='best', framealpha=1.0)
    plt.grid()

    plt.show()
Ejemplo n.º 8
0
 def get_nfw_conc(mass, redshift):
     kw1 = {}
     kw1.update(kws)
     kw1['redshift'] = redshift
     model = NFWProfile(**kw1)
     return model.conc_NFWmodel(prim_haloprop=mass)
Ejemplo n.º 9
0
# halotools.test_installation()

# determine dark mass and virial radius
model = PrebuiltSubhaloModelFactory('behroozi10', redshift = redshift)
stars_mass = 60850451172.24926
# stars_mass in units Msun from simulation
log_stars_mass = np.log10(stars_mass)
log_dark_mass = model.mean_log_halo_mass(log_stellar_mass=log_stars_mass)
dm_stellar = 10**log_dark_mass
virial = halo_mass_to_halo_radius(dm_stellar, cosmo, redshift, mdef)
virial_kpc = (virial * u.Mpc).to('kpc') / h
virial_rad = np.arange(radmin, virial_kpc.value, inc)
scaled_rad = virial_rad / np.max(virial_rad)

# calculate the density threshold for dimensionless mass density calculation
nfw = NFWProfile()
rho_thresh = density_threshold(cosmo, redshift, mdef)
# rho_thresh in units Msun*h^2/Mpc^3
rho_units = (rho_thresh * u.Msun / u.Mpc**3).to('Msun/kpc3') * h**2
dimless_massdens = nfw.dimensionless_mass_density(scaled_rad, conc)
mass_dens = dimless_massdens * rho_units
# mass_dens is in units Msun/kpc^3

# create an array of heights to take vertical components into account
height_arr = np.arange(-z, z+1)
height_scale = height_arr / z

# prepare arrays
nfw_heights = np.zeros(len(height_scale))
nfw_avg = np.zeros(len(scaled_rad))
Ejemplo n.º 10
0
    def __init__(self,
                 z,
                 m200c=None,
                 r200c=None,
                 c=None,
                 cM_err=False,
                 cosmo=cm.OuterRim_params,
                 seed=None):
        """
        Class for generating NFW test-case input files for the ray tracing modules supplied in
        the directory above. This class is constructed with a halo mass, redshift, and 
        cosmological model, and builds a HaloTools NFWProfile object. The methods provided here 
        can then populate the profile with a particle distribution realization in 3 dimensions, 
        and output the result in the form expected by the raytracing modules.
        
        Parameters
        ----------
        z : float 
            The redshift of the halo.
        m200c : float
            The mass of the halo within a radius containing 200*rho_crit, in M_sun. If not passed, 
            then r200c must be supplied
        r200c : float
            The radius of the halo enclosing a mean density of 200*rho_crit, in Mpc. If not passed,
            then m200c must be supplied.
        c : float, optional 
            The concentration of the halo. If not given, samples from a Gaussian 
            with location and scale suggested by the M-c relation of Child+2018
        cM_err : bool, optional 
            Whether or not to impose scatter on the cM relation used to draw a concentration, 
            in the case that the argument c is not passed. If False, the concentration drawn 
            will always lie exactly on the cM relation used (currently Child+ 2018). Defaults
            to True. In either case, the 'sod_halo_cdelta_error' quntity in the output halo propery
            csv file will be zero.
        cosmo : object, optional
            An AstroPy cosmology object. Defaults to OuterRim parameters.
        seed : float, optional
            Random seed to pass to HaloTools for generation of radial particle positions, and
            use for drawing concentrations and angular positions of particles. Defaults to None
            (giving stochastic output)
        
        Methods
        -------
        populate_halo(r)
            Uses HaloTools to generate a MonteCarlo realization of discrete tracers of the density
            profile (particles)
        output_particles():
            Writes out the particle positions generated by populate_halo() to a form that is prepped 
            for input to the ray tracing modules of this package.
        """

        assert (m200c is not None or r200c is not None
                ), "Either m200c (in M_sun) or r200c (in Mpc) must be supplied"
        self.m200c = m200c
        self.r200c = r200c
        self.redshift = z
        self.cosmo = cosmo
        self.seed = seed

        self.profile = NFWProfile(cosmology=self.cosmo,
                                  redshift=self.redshift,
                                  mdef='200c')

        # HaloTools and Colossus expect masses,radii with h dependence, so scale accordingly on input and output
        if (r200c is None):
            self.m200ch = m200c * cosmo.h  # M_sun/h
            self.r200ch = self.profile.halo_mass_to_halo_radius(
                self.m200ch)  #proper Mpc/h
            self.r200c = self.r200ch / cosmo.h  # proper Mpc
        if (m200c is None):
            self.r200ch = r200c * cosmo.h  # proper Mpc/h
            self.m200ch = self.profile.halo_radius_to_halo_mass(
                self.r200ch)  # M_sun/h
            self.m200c = self.m200ch / cosmo.h  # M_sun

        # these to be filled by populate_halo()
        self.r = None
        self.theta = None
        self.phi = None
        self.mpp = None
        self.max_rfrac = None
        self.populated = False

        if c is not None:
            self.c = c
            self.c_err = 0
        else:
            # if cM_err=True, draw a concentration from gaussian, otherwise use Child+2018 cM relation scatter-free
            rand = np.random.RandomState(self.seed)

            cosmo_colossus = colcos.setCosmology(
                'OuterRim', {
                    'Om0': cosmo.Om0,
                    'Ob0': cosmo.Ob0,
                    'H0': cosmo.H0.value,
                    'sigma8': 0.8,
                    'ns': 0.963,
                    'relspecies': False
                })
            c_u = mass_conc(self.m200ch, '200c', z, model='child18')
            if (cM_err):
                c_sig = c_u / 3
                self.c = rand.normal(loc=c_u, scale=c_sig)
            else:
                self.c = c_u
            self.c_err = 0