Ejemplo n.º 1
0
def get_xiauto_mass_avg(emu, rs, M1min, M1max, M2min, M2max, z):
    '''
    Averages the halo-halo correlation function over mass ranges to return the weighted-by-mass-function mean version
    '''
    from scipy.interpolate import InterpolatedUnivariateSpline as ius
    from scipy.interpolate import RectBivariateSpline as rbs
    from scipy.integrate import dblquad

    # Parameters
    epsabs = 1e-3  # Integration accuracy
    nM = 6  # Number of halo-mass bins in each of M1 and M2 directions

    # Calculations
    nr = len(rs)

    # Number densities of haloes in each sample
    n1 = ndenshalo(emu, M1min, M1max, z)
    n2 = ndenshalo(emu, M2min, M2max, z)

    # Arrays for halo masses
    M1s = mead.logspace(M1min, M1max, nM)
    M2s = mead.logspace(M2min, M2max, nM)

    # Get mass function interpolation
    Ms = emu.massfunc.Mlist
    dndM = emu.massfunc.get_dndM(z)
    log_dndM_interp = ius(np.log(Ms), np.log(dndM))

    # Loop over radii
    xiauto_avg = np.zeros((nr))
    for ir, r in enumerate(rs):

        # Get correlation function interpolation
        # Note that this is not necessarily symmetric because M1, M2 run over different ranges
        xiauto_mass = np.zeros((nM, nM))
        for iM1, M1 in enumerate(M1s):
            for iM2, M2 in enumerate(M2s):
                xiauto_mass[iM1, iM2] = emu.get_xiauto_mass(r, M1, M2, z)
        xiauto_interp = rbs(np.log(M1s), np.log(M2s), xiauto_mass)

        # Integrate interpolated functions
        xiauto_avg[ir], _ = dblquad(
            lambda M1, M2: xiauto_interp(np.log(M1), np.log(M2)) * np.exp(
                log_dndM_interp(np.log(M1)) + log_dndM_interp(np.log(M2))),
            M1min,
            M1max,
            lambda M1: M2min,
            lambda M1: M2max,
            epsabs=epsabs)

    return xiauto_avg / (n1 * n2)
    def plot_growth(self):

        plt.figure(1, figsize=(20, 6))

        amin = 1e-4
        amax = 1.
        na = 128
        a_lin = np.linspace(amin, amax, na)
        a_log = mead.logspace(amin, amax, na)

        # Linear scale
        plt.subplot(121)
        plt.plot(a_lin, self.g(a_lin), 'b-', label='Growth function')
        plt.plot(a_lin, self.f(a_lin), 'r-', label='Growth rate')
        plt.legend()
        plt.xlabel(r'$a$')
        plt.xlim((0, 1.0))
        plt.ylabel(r'$g(a)$ or $f(a)$')
        plt.ylim((0, 1.05))

        # Log scale
        plt.subplot(122)
        plt.semilogx(a_log, self.g(a_log), 'b-', label=r'interpolation')
        plt.semilogx(a_log, self.f(a_log), 'r-', label=r'interpolation')
        plt.xlabel(r'$a$')
        plt.ylabel(r'$g(a)$ or $f(a)$')
        plt.ylim((0, 1.05))

        # Show the plot
        plt.show()
    def plot_distances(self):

        plt.subplots(3, figsize=(20, 6))

        amin = 1e-4
        amax = 1.
        na = 128
        a_lin = np.linspace(amin, amax, na)
        a_log = mead.logspace(amin, amax, na)

        # Plot cosmic distance (dimensionless) vs. a on linear scale
        plt.subplot(121)
        plt.plot(a_lin, self.r(a_lin), 'g-', label='Comoving distance')
        plt.plot(a_lin, self.rp(a_lin), 'b-', label='Particle horizon')
        plt.plot(a_lin, self.t(a_lin), 'r-', label='Age')
        plt.legend()
        plt.xlabel(r'$a$')
        plt.ylabel(r'$r(a)$ or $t(a)$')

        # Plot cosmic distance (dimensionless) vs. a on log scale
        plt.subplot(122)
        plt.loglog(a_log, self.r(a_log), 'g-', label='interpolation')
        plt.loglog(a_log, self.rp(a_log), 'b-', label='interpolation')
        plt.loglog(a_log, self.t(a_log), 'r-', label='interpolation')
        plt.xlabel(r'$a$')
        plt.ylabel(r'$r(a)$ or $t(a)$')
        plt.show()
    def plot_Omegas(self):

        # a range
        amin = 1e-3
        amax = 1.
        na = 129
        a_lintab = np.linspace(amin, amax, na)
        a_logtab = mead.logspace(amin, amax, na)

        plt.figure(1, figsize=(20, 6))

        # Omegas - Linear
        plt.subplot(122)
        plt.plot(a_logtab, self.Omega_r(a_logtab), label=r'$\Omega_r(a)$')
        plt.plot(a_logtab, self.Omega_m(a_logtab), label=r'$\Omega_m(a)$')
        plt.plot(a_logtab, self.Omega_w(a_logtab), label=r'$\Omega_w(a)$')
        plt.plot(a_logtab, self.Omega_v(a_logtab), label=r'$\Omega_v(a)$')
        plt.xlabel(r'$a$')
        plt.ylabel(r'$\Omega_i(a)$')
        plt.legend()

        # Omegas - Log
        plt.subplot(121)
        plt.semilogx(a_logtab, self.Omega_r(a_logtab), label=r'$\Omega_r(a)$')
        plt.semilogx(a_logtab, self.Omega_m(a_logtab), label=r'$\Omega_m(a)$')
        plt.semilogx(a_logtab, self.Omega_w(a_logtab), label=r'$\Omega_w(a)$')
        plt.semilogx(a_logtab, self.Omega_v(a_logtab), label=r'$\Omega_v(a)$')
        plt.xlabel(r'$a$')
        plt.ylabel(r'$\Omega_i(a)$')
        plt.legend()

        plt.figure(2, figsize=(20, 6))

        # w(a) - Linear
        plt.subplot(121)
        plt.axhline(0, c='k', ls=':')
        plt.axhline(1, c='k', ls=':')
        plt.axhline(-1, c='k', ls=':')
        plt.plot(a_lintab, self.w_de(a_lintab))
        plt.xlabel(r'$a$')
        plt.ylabel(r'$w(a)$')
        plt.ylim((-1.05, 1.05))

        # w(a) - Log
        plt.subplot(122)
        plt.axhline(0, c='k', ls=':')
        plt.axhline(1, c='k', ls=':')
        plt.axhline(-1, c='k', ls=':')
        plt.semilogx(a_logtab, self.w_de(a_logtab))
        plt.xlabel(r'$a$')
        plt.ylabel(r'$w(a)$')
        plt.ylim((-1.05, 1.05))

        plt.show()
    def init_growth(self):

        print('Initialise_growth: Solving growth equations')

        # Calculate things associated with the linear growth

        amin = 1e-5
        amax = 1.
        na = 64
        a_tab = mead.logspace(amin, amax, na)

        # Set initial conditions for the ODE integration
        #d_init = a_lintab_nozero[0]
        d_init = amin
        v_init = 1.

        # Function to calculate delta'
        def dd(v, d, a):
            dd = 1.5 * self.Omega_m(a) * d / a**2 - (
                2. + self.AH(a) / self.H2(a)) * v / a
            return dd

        # Function to get delta' and v' in the correct format for odeint
        # Note that it returns [v',delta'] in the 'wrong' order
        def dv(X, t):
            return [X[1], dd(X[1], X[0], t)]

        # Use odeint to get g(a) and f(a) = d ln(g)/d ln(a)
        #gv=odeint(dv,[d_init,v_init],a_lintab_nozero)
        gv = odeint(dv, [d_init, v_init], a_tab)
        g_tab = gv[:, 0]
        f_tab = a_tab * gv[:, 1] / gv[:, 0]

        print('Initialise_growth: ODE solved')

        # Add in the values g(a=0) and f(a=0) if using the 'nonzero' tab
        #g_tab=np.insert(g_tab,0,0.)
        #f_tab=np.insert(f_tab,0,1.)

        print('Initialise_growth: Creating interpolators')

        # Create interpolation function for g(a)
        g_func = interpolate.log_interp1d(a_tab,
                                          g_tab,
                                          kind='cubic',
                                          fill_value='extrapolate')

        def g_vectorize(a):
            if (a < amin):
                return a
            elif (a > 1.):
                print('Error, g(a>1) called:', a)
                return None
            else:
                return g_func(a)

        self.g = np.vectorize(g_vectorize)

        # Create interpolation function for f(a) = dln(g)/dln(a)
        f_func = interpolate.log_interp1d(a_tab,
                                          f_tab,
                                          kind='cubic',
                                          fill_value='extrapolate')

        def f_vectorize(a):
            if (a < amin):
                return 1.
            elif (a > 1.):
                print('Error, f(a>1) called:', a)
                return None
            else:
                return f_func(a)

        self.f = np.vectorize(f_vectorize)

        print('Initialise_growth: Interpolators done')

        # Check values
        print('Initialise_growth: g(0):', self.g(0.))
        print('Initialise_growth: g(amin):', self.g(amin))
        print('Initialise_growth: g(1):', self.g(1.))
        print('Initialise_growth: f(0):', self.f(0.))
        print('Initialise_growth: f(amin):', self.f(amin))
        print('Initialise_growth: f(1):', self.f(1.))
        print()
    def init_distances(self):

        #global r_tab, t_tab, rp_tab
        #global r, t, rp
        #global r0, t0

        # A small number
        small = 0.

        # a values for interpolation
        amin = 1e-5
        amax = 1.
        na = 64
        a_tab = mead.logspace(amin, amax, na)

        ###

        # Integrand for the r(a) calculations and vectorise
        def r_integrand(a):
            return 1. / (self.H(a) * a**2)

        r_integrand_vec = np.vectorize(r_integrand)

        # Function to integrate to get rp(a) (PARTICLE HORIZON) and vectorise
        def rp_integrate(a):
            rp, _ = integrate.quad(r_integrand_vec, 0., a)
            return rp

        rp_integrate_vec = np.vectorize(rp_integrate)

        # Function to integrate to get r(a) and vectorise
        def r_integrate(a):
            r, _ = integrate.quad(r_integrand_vec, a, 1.)
            return r

        r_integrate_vec = np.vectorize(r_integrate)

        ###

        # Integrand for the t(a) calculation and vectorise
        def t_integrand(a):
            return 1. / (self.H(a) * a)

        t_integrand_vec = np.vectorize(t_integrand)

        # Function to integrate to get r(a) and vectorise
        def t_integrate(a):
            t, _ = integrate.quad(t_integrand_vec, 0., a)
            return t

        t_integrate_vec = np.vectorize(t_integrate)

        ###

        # Call the vectorised integration routine
        r_tab = r_integrate_vec(a_tab)
        rp_tab = rp_integrate_vec(a_tab)
        t_tab = t_integrate_vec(a_tab)

        # Add in values r(a=0) and t(a=0) if the 'nonzero' table has been used
        #r_tab=np.insert(r_tab,0,0.)
        #t_tab=np.insert(t_tab,0,0.)

        # Interpolaton function for r(a)
        r_func = interp1d(
            a_tab, r_tab, kind='cubic',
            fill_value='extrapolate')  #This needs to be linear, not log

        def r_vectorize(a):
            if (a <= small):
                return rp_integrate(1.)
            elif (a > 1.):
                print('Error, r(a>1) called:', a)
                return None
            else:
                return r_func(a)

        self.r = np.vectorize(r_vectorize)

        # Interpolaton function for rp(a)
        rp_func = interpolate.log_interp1d(a_tab,
                                           rp_tab,
                                           kind='cubic',
                                           fill_value='extrapolate')

        def rp_vectorize(a):
            if (a <= small):
                return 0.
            elif (a > 1.):
                print('Error, rp(a>1) called:', a)
                return None
            else:
                return rp_func(a)

        self.rp = np.vectorize(rp_vectorize)

        # Interpolaton function for t(a)
        t_func = interpolate.log_interp1d(a_tab,
                                          t_tab,
                                          kind='cubic',
                                          fill_value='extrapolate')

        def t_vectorize(a):
            if (a <= small):
                return 0.
            elif (a > 1.):
                print('Error, t(a>1) called:', a)
                return None
            else:
                return t_func(a)

        self.t = np.vectorize(t_vectorize)

        r0 = self.rp(1.)
        t0 = self.t(1.)
        print('Initialise_distances: Horizon size [dimensionless]:', r0)
        print('Initialise_distances: Horizon size [Mpc/h]:', const.Hdist * r0)
        print('Initialise_distances: Universe age [dimensionless]:', t0)
        print('Initialise_distances: Universe age [Gyr/h]:', const.Htime * t0)
        print('Initialise_distances: r(0):', self.r(0.))
        print('Initialise_distances: rp(0):', self.rp(0.))
        print('Initialise_distances: t(0):', self.t(0.))
        print()