예제 #1
0
def mcerrors(sim,
             initparams,
             rmin='4 kpc',
             rmax='10 kpc',
             zmin='0 kpc',
             zmax='4 kpc'):
    if isinstance(rmin, str): rmin = un.Unit(rmin)
    if isinstance(rmax, str): rmax = un.Unit(rmax)
    if isinstance(zmin, str): zmin = un.Unit(zmin)
    if isinstance(zmax, str): zmax = un.Unit(zmax)

    annulus = f.Disc(rmax, zmax) & ~f.Disc(rmin, zmax) & ~f.Disc(rmax, zmin)

    nwalkers, ndim = 6, 2
    sampler = emcee.EnsembleSampler(
        nwalkers,
        ndim,
        twoexp_likelihood,
        args=(np.array(sim.s[annulus]['rxy'].in_units('kpc')),
              np.array(sim.s[annulus]['z'].in_units('kpc')), rmin, rmax, zmin,
              zmax))

    p0 = [np.random.rand(ndim) for i in range(nwalkers)]

    sampler.run_mcmc(p0, 1000)
    #import pdb; pdb.set_trace()
    return np.std(sampler.flatchain[:, 0]), np.std(
        sampler.flatchain[:, 1] / 2.0)
예제 #2
0
def test_units_addition():
    _2_kpc = units.Unit("2.0 kpc")
    _3_Mpc = units.Unit("3.0 Mpc")
    npt.assert_allclose((_2_kpc + _3_Mpc).in_units("kpc"), 3002)
    npt.assert_allclose((_3_Mpc - _2_kpc).in_units("kpc"), 2998)
    npt.assert_allclose((_2_kpc + 2.0).in_units("kpc"), 4.0)
    npt.assert_allclose((_3_Mpc + 2.0).in_units("kpc"), 5000)
예제 #3
0
def test_units_pickle():
    import pickle
    pick = lambda x: pickle.loads(pickle.dumps(x))

    assert pick(units.km) is units.km  # named
    assert pick(units.m) is units.m  # irreducible
    assert pick(units.Unit("km s^-1 Msol^-5")) == units.Unit("km s^-1 Msol^-5")
예제 #4
0
def plot_profile(profile,
                 fith=1.0,
                 xy=(0, 0),
                 outfig=False,
                 units='m_p cm^-2',
                 title=False,
                 rmin='4 kpc',
                 rmax='10 kpc'):
    import matplotlib.pyplot as plt

    if isinstance(rmin, str): rmin = un.Unit(rmin)
    if isinstance(rmax, str): rmax = un.Unit(rmax)

    logN = np.log10(profile['density'].in_units(units))
    good = np.isfinite(logN)
    rad = profile['rbins'].in_units('kpc')

    # Do simple fit to get normalization
    expfit = np.polyfit(np.array(rad[good]), np.array(logN[good]), 1)
    # 1.0857 is how many magnitudes a 1/e decrease is
    h = -1.0857 / expfit[0]
    N_0 = expfit[1]
    #N_0 = np.log10(np.sum(vprofile['density'].in_units(units)) /
    #               (4.0*hz*(math.tanh(zmax/(2.0*hz))-math.tanh(zmin/(2.0*hz))))/
    #               (2.0*math.pi*hr*(-math.exp(-rmax/hr)*(hr + rmax) +
    #                                 math.exp(-rmin/hr)*(hr + rmin))))
    #N_0=np.log10(np.sum(profile['density'].in_units(units)) /
    #             2.0*math.pi*fith*(-np.exp(-rmax/fith)*(fith + rmax) +
    #                                np.exp(-rmin/fith)*(fith + rmin)))

    plt.errorbar(
        rad[good],
        logN[good],
        yerr=np.log10(profile['density'][good].in_units(units)) / np.sqrt(
            profile['n'][good]),
        fmt='o')
    plt.plot(
        rad,
        N_0 + np.log10(np.exp(-rad / fith)),
        label='h: %2.1f kpc; $N_0$: %2.1f' % (fith, N_0),
        linestyle='dashed')
    if title: plt.title(title)
    plt.xlabel('distance [kpc]')
    plt.ylabel('log$_{10}$(surface density [$' +
               pynbody.units.Unit(units).latex() + '$])')
    plt.legend(loc=0)
    plt.title('x = %.2f y = %.2f' % (xy[0], xy[1]))
    if outfig:
        plt.savefig(outfig + '.png')
예제 #5
0
def plot_sech_profile(profile,
                      fith=1.0,
                      outfig=False,
                      units='m_p cm^-2',
                      title=False,
                      zmin=0.0,
                      zmax=4.0,
                      xy=(0, 0)):
    import matplotlib.pyplot as plt

    logN = np.log10(profile['density'].in_units(units))
    good = np.isfinite(logN)
    rad = profile['rbins'].in_units('kpc')
    if isinstance(zmin, str): zmin = un.Unit(zmin)
    if isinstance(zmax, str): zmax = un.Unit(zmax)

    # Do simple fit to get normalization
    #    expfit = np.polyfit(np.array(rad[good]), np.array(logN[good]), 1)
    # 1.0857 is how many magnitudes a 1/e decrease is
    #h=-1.0857/expfit[0]
    #   N_0=expfit[1]
    N_0 = np.log10(
        np.sum(profile['density'].in_units(units)) / 2 * fith *
        (math.tanh(zmax / (2 * fith)) - math.tanh(zmin / (2 * fith))))

    print("N_0: %g" % N_0)
    plt.errorbar(
        rad[good],
        logN[good],
        yerr=np.log10(profile['density'][good].in_units(units)) / np.sqrt(
            profile['n'][good]),
        fmt='o')
    plt.plot(
        rad,
        N_0 + np.log10(np.cosh(rad / (2.0 * fith))**-2),
        label='h: %2.1f kpc; $N_0$: %2.1f' % (fith, N_0),
        linestyle='dashed')
    if title: plt.title(title)
    plt.xlabel('distance [kpc]')
    plt.ylabel('log$_{10}$(surface density [$' +
               pynbody.units.Unit(units).latex() + '$])')
    plt.legend(loc=0)
    plt.title('x = %.2f y = %.2f' % (xy[0], xy[1]))

    if outfig:
        plt.savefig(outfig + '.png')
예제 #6
0
def test_units_parser():
    testunit = units.Unit("kpc a s^-2/3 Myr^2/3")
    print("Unit as parsed: ", testunit)
    testunit /= units.kpc
    testunit /= units.a
    testunit /= units.s ** (-2, 3)
    testunit /= units.Myr ** (2, 3)
    print("This should be one: ", testunit)
    assert abs(testunit.dimensionless_constant() - 1) < 1.e-10
예제 #7
0
    def units(self, u):
        # print 'SimArray::units::u\t', u
        if not isinstance(u, units.UnitBase) and u is not None:
            u = units.Unit(str(u))

        if hasattr(self.base, 'units'):
            self.base.units = u
        else:
            if hasattr(u, "_no_unit"):
                self._units = None
            else:
                self._units = u
예제 #8
0
 def __init__(self, **kwargs):
     self.__profile = kwargs.get('profile', density_profiles.alphabetagamma)
     self.__drhodr = kwargs.get('drhodr',
                                density_profiles.dalphabetagammadr)
     self.__d2rhodr2 = kwargs.get('d2rhodr2',
                                  density_profiles.d2alphabetagammadr2)
     self.__pars = kwargs.get('pars', {
         'alpha': 1.,
         'beta': 3.,
         'gamma': 1.,
         'c': 10.,
         'factor': 0.1
     })
     if self.__profile == density_profiles.alphabetagamma and self.__pars[
             'beta'] <= 3.:
         if 'factor' not in self.__pars.keys(): self.__pars['factor'] = 0.1
     self.__m_vir = kwargs.get('m_vir', '1e12 Msol')
     self.__m_vir = units.Unit(self.__m_vir)
     self.__h = kwargs.get('h', 0.7)
     self.__overden = kwargs.get('overden', 200.)
     self.__r_vir = tools.calc_r_vir(self.__m_vir, self.__h, self.__overden)
     self.__r_s = self.__r_vir / self.__pars['c']
     self.__n_particles = int(kwargs.get('n_particles', 1e5))
     self.__logxmax_rho = np.log10(self.__pars['c']) + 2.
     # Make sure to sample well inside the gravitational softening
     self.__logxmin_rho = self.__logxmax_rho - .5 * np.log10(
         self.__n_particles) - 3.
     self.__logxmax_dist_func = np.log10(self.__pars['c']) + 13.
     self.__logxmin_dist_func = self.__logxmax_dist_func - .5 * np.log10(
         self.__n_particles)
     self.__logxmin_dist_func -= 14.
     self.__n_sample_rho = int(kwargs.get('n_sample_rho', 1e4))
     self.__n_sample_dist_func = int(kwargs.get('n_sample_dist_func', 1e2))
     self.__n_sample_dist_func_rho = int(
         kwargs.get('n_sample_dist_func_rho', 1e4))
     self.__random_seed = kwargs.get('random_seed', 4)
     if 'prng' in kwargs.keys():
         self.__prng = kwargs['prng']
     else:
         self.__prng = np.random.RandomState(self.__random_seed)
     self.__spline_order = kwargs.get('spline_order', 3)
     self.__progress_bar = kwargs.get('progress_bar', False)
     self.__no_bulk_vel = kwargs.get('no_bulk_vel', True)
     self.__x_rho = np.logspace(self.__logxmin_rho, self.__logxmax_rho,
                                self.__n_sample_rho)
     self.__do_velocities = kwargs.get('do_velocities', True)
     self.__gas = kwargs.get('gas', False)
     if 'snap' in kwargs.keys():
         self.sim = kwargs['snap']
     elif self.__gas:
         self.sim = snapshot._new(gas=self.__n_particles)
     else:
         self.sim = snapshot._new(self.__n_particles)
예제 #9
0
def two_exp_fit(sim,
                rmin='4 kpc',
                rmax='10 kpc',
                zmin='0 kpc',
                zmax='4 kpc',
                func=neg2expl):

    if isinstance(rmin, str): rmin = un.Unit(rmin)
    if isinstance(rmax, str): rmax = un.Unit(rmax)
    if isinstance(zmin, str): zmin = un.Unit(zmin)
    if isinstance(zmax, str): zmax = un.Unit(zmax)

    annulus = f.Disc(rmax, zmax) & ~f.Disc(rmin, zmax) & ~f.Disc(rmax, zmin)
    fitnum = len(sim.s[annulus])
    print("Fitting %d stars" % (fitnum))
    if fitnum > 100:
        hr, z0 = opt.fmin_powell(
            func, [1.0, 1.0],
            args=(sim.s[annulus]['rxy'].in_units('kpc'),
                  sim.s[annulus]['z'].in_units('kpc'), rmin, rmax, zmin, zmax))
        return hr, z0, fitnum
    else:
        return float('NaN'), float('NaN'), fitnum
예제 #10
0
def test_units_copy():
    # These should succeed

    import copy
    copy.copy(units.Unit("Msol kpc^-1")).ratio("kg km^-1")
    copy.deepcopy(units.Unit("Msol kpc^-1")).ratio("kg km^-1")
예제 #11
0
def test_units_substitution():
    numacc((units.a / units.h).in_units(units.Unit(""), a=22, h=2), 11)
s = pynbody.load('../data/g15784.lr.01024.gz')

# load the halos catalogue

h = s.halos()

h1 = h[1]
print h1
# center the largest halo
pynbody.analysis.angmom.faceon(h1)

# set the units
s.physical_units()

# image

pynbody.plot.image(h1.s, width=100, cmap="Blues")

plt.show()
# apply the solar neighbourhood filter
"""
function that returns a filter which selects particles
    in a disc between radii `r1` and `r2` and thickness `height`.
"""

r1 = units.Unit("7.00e+00 kpc")
r2 = units.Unit("9.00e+00 kpc")
height = units.Unit("16.00e+00 kpc")
filter = pynbody.filt.SolarNeighborhood(r1, r2, height, cen=(0, 0, 0))
예제 #13
0
def calc_r_vir(m_vir, h, overden):
    """Calculate virial radius (w.r.t. rho_crit)"""
    rvir3 = 3. / 4. / np.pi / overden * m_vir / calc_rho_crit(h)
    return units.Unit('{0:.64g} kpc'.format(
        float(rvir3.in_units('kpc**3')**(1. / 3.))))
예제 #14
0
 def __init__(self, **kwargs):
     self.__kwargs = kwargs
     self.__profile = kwargs.get('profile', density_profiles.alphabetagamma)
     self.__drhodr = kwargs.get('drhodr',
                                density_profiles.dalphabetagammadr)
     self.__d2rhodr2 = kwargs.get('d2rhodr2',
                                  density_profiles.d2alphabetagammadr2)
     self.__pars = kwargs.get('pars', {
         'alpha': 1.,
         'beta': 3.,
         'gamma': 1.,
         'c': 10.,
         'factor': 0.1
     })
     if self.__profile == density_profiles.alphabetagamma and self.__pars[
             'beta'] <= 3.:
         if 'factor' not in self.__pars.keys(): self.__pars['factor'] = 0.1
     self.__m_vir = kwargs.get('m_vir', '1e12 Msol')
     self.__m_vir = units.Unit(self.__m_vir)
     self.__h = kwargs.get('h', 0.7)
     self.__overden = kwargs.get('overden', 200.)
     self.__r_vir = tools.calc_r_vir(self.__m_vir, self.__h, self.__overden)
     self.__r_s = self.__r_vir / self.__pars['c']
     self.__n_particles = int(kwargs.get('n_particles', 1e5))
     self.__logxmax_rho = np.log10(self.__pars['c']) + 2.
     # Make sure to sample well inside the gravitational softening
     self.__logxmin_rho = self.__logxmax_rho - .5 * np.log10(
         self.__n_particles) - 3.
     self.__logxmin_dist_func = kwargs.get('logxmin_dist_func', -3.)
     self.__logxmax_dist_func = kwargs.get('logxmax_dist_func', 14.)
     self.__n_sample_rho = int(kwargs.get('n_sample_rho', 1e4))
     self.__n_sample_dist_func = int(kwargs.get('n_sample_dist_func', 1e2))
     self.__n_sample_dist_func_rho = int(
         kwargs.get('n_sample_dist_func_rho', 1e4))
     self.__random_seed = kwargs.get('random_seed', 4)
     if 'prng' in kwargs.keys():
         self.__prng = kwargs['prng']
     else:
         self.__prng = np.random.RandomState(self.__random_seed)
     self.__spline_order = kwargs.get('spline_order', 3)
     self.__progress_bar = kwargs.get('progress_bar', False)
     self.__no_bulk_vel = kwargs.get('no_bulk_vel', True)
     self.__x_rho = np.logspace(self.__logxmin_rho, self.__logxmax_rho,
                                self.__n_sample_rho)
     self.__f_bary = kwargs.get('f_bary', 0.1)
     self.__mu = kwargs.get('mu', 1.3)
     self.__spin_parameter = kwargs.get('spin_parameter', 0.04)
     self.__rot_balanced = kwargs.get('rot_balanced', False)
     # Different gas profiles are not yet implemented or successfully tested
     self.__gas_profile = self.__profile
     self.__gas_pars = self.__pars
     #self.__gas_profile = kwargs.get('gas_profile', density_profiles.alphabetagamma)
     #self.__gas_pars = kwargs.get('gas_pars', {'alpha': 1., 'beta': 3., 'gamma': 1.,
     #   'c': 10., 'factor': 0.1})
     self.__r_s_gas = self.__r_vir / self.__gas_pars['c']
     #self.__vel_prof = kwargs.get('vel_prof', None)
     self.__vel_pars = kwargs.get(
         'vel_pars', {
             'rs_v': array.SimArray(1., 'kpc'),
             'c': self.__pars['c'],
             'prefac': 1.,
             'factor': 1.
         })
     self.__n_gas_particles = int(
         kwargs.get('n_gas_particles', self.__n_particles))
     self.__ang_mom_prof = kwargs.get('ang_mom_prof',
                                      am_profiles.bullock_prof)
     self.__ang_mom_pars = kwargs.get('ang_mom_pars', {'mu': self.__mu})
     self.__fname = kwargs.get('fname', 'halo.out')
     # Careful here: as of now, only the output as tipsy files has been successfully tested
     self.__type = {
         'gadget': gadget.GadgetSnap,
         'grafic': grafic.GrafICSnap,
         'nchilada': nchilada.NchiladaSnap,
         'ramses': ramses.RamsesSnap,
         'tipsy': tipsy.TipsySnap
     }[kwargs.get('type', 'tipsy')]
     self.sim = new(dm=self.__n_particles, gas=self.__n_gas_particles)
     self.sim.physical_units()
예제 #15
0
def render(sim,
           filename=None,
           r_band='i',
           g_band='v',
           b_band='u',
           r_scale=0.5,
           g_scale=1.0,
           b_scale=1.0,
           dynamic_range=2.0,
           mag_range=None,
           width=50,
           starsize=None,
           plot=True,
           axes=None,
           ret_im=False,
           clear=True,
           ret_range=False):
    '''
    Make a 3-color image of stars.

    The colors are based on magnitudes found using stellar Marigo
    stellar population code.  However there is no radiative transfer
    to account for dust.

    Returns: If ret_im=True, an NxNx3 array representing an RGB image

    **Optional keyword arguments:**

       *filename*: string (default: None)
         Filename to be written to (if a filename is specified)

       *r_band*: string (default: 'i')
         Determines which Johnston filter will go into the image red channel

       *g_band*: string (default: 'v')
         Determines which Johnston filter will go into the image green channel

       *b_band*: string (default: 'b')
         Determines which Johnston filter will go into the image blue channel

       *r_scale*: float (default: 0.5)
         The scaling of the red channel before channels are combined

       *g_scale*: float (default: 1.0)
         The scaling of the green channel before channels are combined

       *b_scale*: float (default: 1.0)
         The scaling of the blue channel before channels are combined

       *width*: float in kpc (default:50)
         Sets the size of the image field in kpc

       *starsize*: float in kpc (default: None)
         If not None, sets the maximum size of stars in the image

       *ret_im*: bool (default: False)
         if True, the NxNx3 image array is returned

       *ret_range*: bool (default: False)
         if True, the range of the image in mag arcsec^-2 is returned.

       *plot*: bool (default: True)
         if True, the image is plotted

       *axes*: matplotlib axes object (deault: None)
         if not None, the axes object to plot to

       *dynamic_range*: float (default: 2.0)
         The number of dex in luminosity over which the image brightness ranges

       *mag_range*: float, float (default: None)
         If provided, the brightest and faintest surface brightnesses in the range,
         in mag arcsec^-2. Takes precedence over dynamic_range.
    '''

    if isinstance(width, str) or issubclass(width.__class__, _units.UnitBase):
        if isinstance(width, str):
            width = _units.Unit(width)
        width = width.in_units(sim['pos'].units, **sim.conversion_context())

    if starsize is not None:
        smf = filt.HighPass('smooth', str(starsize) + ' kpc')
        sim.s[smf]['smooth'] = array.SimArray(starsize, 'kpc', sim=sim)

    r = image(sim.s,
              qty=r_band + '_lum_den',
              width=width,
              log=False,
              units="pc^-2",
              clear=False,
              noplot=True) * r_scale
    g = image(sim.s,
              qty=g_band + '_lum_den',
              width=width,
              log=False,
              units="pc^-2",
              clear=False,
              noplot=True) * g_scale
    b = image(sim.s,
              qty=b_band + '_lum_den',
              width=width,
              log=False,
              units="pc^-2",
              clear=False,
              noplot=True) * b_scale

    # convert all channels to mag arcsec^-2

    r = pynbody.plot.stars.convert_to_mag_arcsec2(r)
    g = pynbody.plot.stars.convert_to_mag_arcsec2(g)
    b = pynbody.plot.stars.convert_to_mag_arcsec2(b)

    #r,g,b = nw_scale_rgb(r,g,b)
    #r,g,b = nw_arcsinh_fit(r,g,b)

    if mag_range is None:
        rgbim, mag_max = pynbody.plot.stars.combine(r, g, b,
                                                    dynamic_range * 2.5)
        mag_min = mag_max + 2.5 * dynamic_range
    else:
        mag_max, mag_min = mag_range
        rgbim, mag_max = pynbody.plot.stars.combine(r, g, b, mag_min - mag_max,
                                                    mag_max)

    if plot:
        if clear:
            plt.clf()
        if axes is None:
            axes = plt.gca()

        if axes:
            axes.imshow(rgbim[::-1, :],
                        extent=(-width / 2, width / 2, -width / 2, width / 2))
            axes.set_xlabel('x [' + str(sim.s['x'].units) + ']')
            axes.set_ylabel('y [' + str(sim.s['y'].units) + ']')
            plt.draw()

    if filename:
        plt.axis('off')
        plt.savefig(filename, dpi=1600, figsize=(25, 25), bbox_inches='tight')

    if ret_im:
        return rgbim

    if ret_range:
        return mag_max, mag_min
예제 #16
0
def plot_two_profiles(vprofile,
                      rprofile,
                      hz=1.0,
                      hr=1.0,
                      outfig=False,
                      units='m_p cm^-2',
                      title=False,
                      rmin='4 kpc',
                      rmax='10 kpc',
                      zmin='0 kpc',
                      zmax='4 kpc'):
    import matplotlib.pyplot as plt

    if outfig: plt.ioff()
    else: plt.ion()
    f, ax = plt.subplots(1, 2)

    if isinstance(rmin, str): rmin = un.Unit(rmin).in_units('kpc')
    if isinstance(rmax, str): rmax = un.Unit(rmax).in_units('kpc')
    if isinstance(zmin, str): zmin = un.Unit(zmin).in_units('kpc')
    if isinstance(zmax, str): zmax = un.Unit(zmax).in_units('kpc')

    vrad = vprofile['rbins'].in_units('kpc')
    vpmass = vprofile['mass'].in_units('Msol')

    dz = vprofile['rbins'].in_units('kpc')[1] - vprofile['rbins'].in_units(
        'kpc')[0]
    vbinsize = math.pi * (rmax * rmax - rmin * rmin) * dz

    vN_0 = (np.sum(vpmass / vbinsize * dz) /
            (2.0 * hz *
             (math.tanh(zmax / (2.0 * hz)) - math.tanh(zmin / (2.0 * hz)))))

    ax[0].errorbar(
        vrad,
        vpmass / vbinsize,
        yerr=vpmass / vbinsize / np.sqrt(vprofile['n']),
        fmt='o')
    ax[0].semilogy(
        vrad,
        vN_0 * (np.cosh(vrad / (2.0 * hz))**-2),
        label='h: %2.1f kpc; $N_0$: %2.1f' % (hz, vN_0),
        linestyle='dashed')
    if title: ax[0].set_title(title)
    ax[0].set_xlabel('Z [kpc]')
    ax[0].set_ylabel('Density [M$_\odot$ kpc$^{-3}$]')
    ax[0].legend(loc=0)

    rrad = rprofile['rbins'].in_units('kpc')
    rpmass = rprofile['mass'].in_units('Msol')

    rbinsize = rprofile._binsize.in_units('kpc^2') * (zmax - zmin)
    rN_0 = (np.sum(rpmass / rbinsize * rprofile['dr'].in_units('kpc')) /
            (2.0 * math.pi * hr *
             (-math.exp(-rmax / hr) * (hr + rmax) + math.exp(-rmin / hr) *
              (hr + rmin))))

    ax[1].errorbar(
        rrad,
        rpmass / rbinsize,
        yerr=rpmass / rbinsize / np.sqrt(rprofile['n']),
        fmt='o')
    ax[1].semilogy(
        rrad,
        rN_0 * (np.exp(-rrad / hr)),
        label='h: %2.1f kpc; $N_0$: %2.1f' % (hr, rN_0),
        linestyle='dashed')
    ax[1].set_xlabel('R [kpc]')
    ax[1].set_ylabel('Density [M$_\odot$ kpc$^{-3}$]')
    ax[1].legend(loc=0)
    if outfig:
        plt.savefig(outfig + '.png')
    plt.clf()
    plt.close()
예제 #17
0
def create_ics(**kwargs):
    """
    A convenience function which basically does everything for you. You only need to define
    the density profile and its first and second derivative with respect to radius. You can
    also use a class of predefined density profiles including Hernquist, NFW and Jaffe
    profiles or isothermal spheres i.e. the alpha-beta-gamma profiles with the respective
    parameters.

    As of now the code only supports the gas and dark matter density to share the same radial
    dependence with a spatially constant ratio of gas to dark matter density.

    There are a number of parameters you get to set. The most important ones are (default
    values in parantheses)

    Virial mass: m_vir ('1e12 Msol')

    Gas halo spin: spin_parameter (0.04)

    Dictionary of parameters which are passed as an argument to the density profile function:
        pars ({'alpha': 1., 'beta': 3., 'gamma': 1., 'c': 10., 'factor': 0.1})

        These are the parameters for the alpha-beta-gamma models. 'c' is the halo
        concentration in these models and 'factor' is the relative scale outside the virial
        radius at which halos with beta <= 3 are smoothly truncated to ensure a finite
        halo mass.

    Particle number (DM and gas respectively): n_particles (1e5)

    Gas fraction of the halo: f_bary (0.1)

    Output file name: f_name ('halo.out')
    
    Examples:
    ---------

    Hernquist:
    >>> from pyICs.density_profiles import *
    >>> pars = {'alpha': 1., 'beta': 4., 'gamma': 1.}
    >>> sim = create_ics(profile=alphabetagamma, drhodr=dalphabetagammadr,
    >>>     d2rhodr2=d2alphabetagammadr2, pars=pars, m_vir='1e12 Msol', n_particles=1e6)
    >>> sim
    <SimSnap "<created>" len=1000000>

    Arbitrary:
    ----------
    First the density profile and its first and second derivative with respect to the
    dimensionless radius x = r/R_s need to be defined analytically. They need to
    accept the two argumets 'x' and 'pars'. If pars is not needed, it can just be set
    to 'None' but the function definition must accept a 'pars' argument.
    >>> def rho(x, pars):
        ...
        return rho_of_x
    >>> def drhodr(x, pars):
        ...
        return drhodr_of_x
    >>> def d2rhodr2(x, pars):
        ...
        return d2rhodr2_of_x

    Then define specific parameters for that function (can be set to 'None').
    >>> pars = ...
    >>> myhalo = create_ics(profile=rho, drhodr=drhodr, d2rhodr2=d2rhodr2, pars=pars)

    """

    args = {}
    m_vir = kwargs.get('m_vir', '1e12 Msol')
    args['m_vir'] = units.Unit(m_vir)
    args['h'] = kwargs.get('h', 0.7)
    args['overden'] = kwargs.get('overden', 200)
    args['pars'] = kwargs.get('pars', {'alpha': 1., 'beta': 3., 'gamma': 1.,
        'c': 10., 'factor': 0.1})
    profile = kwargs.get('profile', density_profiles.alphabetagamma)
    if profile == density_profiles.alphabetagamma:
        if args['pars']['beta'] <= 3. and 'factor' not in args['pars'].keys():
            args['pars']['factor'] = 0.1
        if 'c' not in args['pars'].keys():
            args['pars']['c'] = 10.
    else:
        unit = kwargs.get('length_unit', '1 kpc')
        r_vir = tools.calc_r_vir(args['m_vir'], args['h'], args['overden'])
        args['c'] = r_vir.in_units(unit)
    kwargs.update(args)
    halo = equilibrium_halos.EquilibriumHalo(**kwargs)
    halo.make_halo()
    halo.finalize()
    return halo.sim
예제 #18
0
def sim_array_to_unit(arr):
    if isinstance(arr, units.UnitBase):
        return arr
    return float(arr) * units.Unit('{0}'.format(arr.units))
예제 #19
0
def calc_rho_crit(h):
    """Calculate critical density for given Hubble constant"""
    return 3. * h**2 * units.Unit(
        '1e2 km s**-1 Mpc**-1')**2 / 8. / np.pi / units.G
예제 #20
0
def test_dimensionless_addition():
    dimless_unit = units.Unit("0.5")
    print(dimless_unit - 0.25)
    npt.assert_allclose(float(dimless_unit - 0.25), 0.25)
    npt.assert_allclose(float(dimless_unit + 0.25), 0.75)