def _compute_sigma(self, redshifts): if not self.cosmology_is_set: raise Exception("Must set_cosmology() first.") redshifts = np.array(redshifts) if redshifts.ndim > 1: raise Exception("Redshifts be either a scalar or 1D array.") h, Omega_m = self.h, self.Omega_m #Hubble constant and matter fraction k, M = self.k, self.M #wavenumbers and halo masses Nk = len(k) NM = len(M) kh = k / h #h/Mpc for i, z in enumerate(np.atleast_1d(redshifts)): if z in self.computed_sigma2.keys(): continue p = np.array([self.cc.pk_lin(ki, z) for ki in k]) * h**3 #[Mpc/h]^3 sigma2 = np.zeros_like(M) dsigma2dM = np.zeros_like(M) _lib.sigma2_at_M_arr(_dc(M), NM, _dc(kh), _dc(p), Nk, Omega_m, _dc(sigma2)) _lib.dsigma2dM_at_M_arr(_dc(M), NM, _dc(kh), _dc(p), Nk, Omega_m, _dc(dsigma2dM)) self.computed_sigma2[z] = sigma2 self.computed_dsigma2dM[z] = dsigma2dM self.computed_sigma2_splines[z] = IUS(np.log(self.M), sigma2) self.computed_dsigma2dM_splines[z] = IUS(np.log(self.M), dsigma2dM) self.computed_pk[z] = p continue return
def add_tracer(self, z, b, dNdz, p=1.6): print(f'p = {p:.1f}') # dz/dr dNdr_spl = IUS(self.Dc(z), dNdz * self.h(z), ext=1) dNdr_tot = romberg(dNdr_spl, self.Dc(z.min()), self.Dc(z.max()), divmax=1000) #print(dNdr_tot) # bias b_spl = IUS(self.Dc(z), b, ext=1) # growth d_spl = IUS(self.Dc(z), self.Dlin(z), ext=1) # growth rate: f = dlnD/dlna f_spl = IUS(self.Dc(z), self.f(z), ext=1) # prepare kernels self.fr_wk = lambda r: r * b_spl(r) * d_spl(r) * (dNdr_spl( r) / dNdr_tot) # W_ell: r*b*(D(r)/D(0))*dN/dr self.fr_wrk = lambda r: r * f_spl(r) * d_spl(r) * (dNdr_spl( r) / dNdr_tot) # Wr_ell:r*f*(D(r)/D(0))*dN/dr self.fr_wkfnl = lambda r: r * (b_spl(r) - p) * (dNdr_spl( r) / dNdr_tot) # Wfnl_ell:r*(b-p)*dN/dr self.kernels_ready = False
def loop_interpolators(self, trim=[0, 1], offset=0.75, full=False): # outer loop coordinate interpolators r, z = self.x['cl']['r'], self.x['cl']['z'] self.fun = {'in': {}, 'out': {}} for side, sign in zip(['in', 'out', 'cl'], [-1, 1, 1]): # inner/outer loop offset r, z = self.x[side]['r'], self.x[side]['z'] index = self.transition_index(r, z) r = r[index['lower'] + 1:index['upper']] z = z[index['lower'] + 1:index['upper']] r, z = geom.offset(r, z, sign * offset) if full: # full loop (including nose) rmid, zmid = np.mean([r[0], r[-1]]), np.mean([z[0], z[-1]]) r = np.append(rmid, r) r = np.append(r, rmid) z = np.append(zmid, z) z = np.append(z, zmid) l = geom.length(r, z) lt = np.linspace(trim[0], trim[1], int(np.diff(trim) * len(l))) r, z = interp1d(l, r)(lt), interp1d(l, z)(lt) l = np.linspace(0, 1, len(r)) self.fun[side] = {'r': IUS(l, r), 'z': IUS(l, z)} self.fun[side]['L'] = geom.length(r, z, norm=False)[-1] self.fun[side]['dr'] = self.fun[side]['r'].derivative() self.fun[side]['dz'] = self.fun[side]['z'].derivative()
def spline_accelerometer(feature_vec, kk=4): """ Given a 128 segment accelerometer feature vector separated as [a_x1, a_y1, a_z1, a_x2, ... , a_z128] we fit the data with a univariate spline """ xline = feature_vec[0::3] #*np.hanning(len(feature_vec)//3) # xline = np.real(np.fft.ifft(np.pad(np.fft.fft(xline)[103:-103],103))) yline = feature_vec[1::3] #*np.hanning(len(feature_vec)//3) # yline = np.real(np.fft.ifft(np.pad(np.fft.fft(yline)[103:-103],103))) zline = feature_vec[2::3] #*np.hanning(len(feature_vec)//3) # zline = np.real(np.fft.ifft(np.pad(np.fft.fft(zline)[103:-103],103))) #spline the accleration, aka alpha' num = len(feature_vec) / 3 t = np.arange(0, num) #define time interval a_x_spline = IUS(t, xline, k=kk) a_y_spline = IUS(t, yline, k=kk) a_z_spline = IUS(t, zline, k=kk) return a_x_spline, a_y_spline, a_z_spline
def _unboxHermiteGeneral(self, lam_range, fullg_r, fullg_a, fullg_e): #Construct hermite vlaues m_herm_r = self._cubic_mono_hermite_spline(lam_range, fullg_r) m_herm_a = self._cubic_mono_hermite_spline(lam_range, fullg_a) m_herm_e = self._cubic_mono_hermite_spline(lam_range, fullg_e) interm_n = 100 (xout_r, yout_r, dr) = self._buildHermite(lam_range, fullg_r, interm_n) (xout_a, yout_a, da) = self._buildHermite(lam_range, fullg_a, interm_n) (xout_e, yout_e, de) = self._buildHermite(lam_range, fullg_e, interm_n) #Constuct functions, not worying about second derivative for now self.h_r = lambda L: self._hermite_spline_point( L, lam_range, fullg_r, m_herm_r, 'point') self.dh_r = lambda L: self._hermite_spline_point( L, lam_range, fullg_r, m_herm_r, 'der') self.h_a = lambda L: self._hermite_spline_point( L, lam_range, fullg_a, m_herm_a, 'point') self.dh_a = lambda L: self._hermite_spline_point( L, lam_range, fullg_a, m_herm_a, 'der') self.h_e = lambda L: self._hermite_spline_point( L, lam_range, fullg_e, m_herm_e, 'point') self.dh_e = lambda L: self._hermite_spline_point( L, lam_range, fullg_e, m_herm_e, 'der') self.h_r_inv = IUS(yout_r, xout_r) self.h_a_inv = IUS(yout_a, xout_a) self.h_e_inv = IUS(yout_e, xout_e)
def compute_splines(self): # To be called after set_model self.lag_spline = IUS(self.ins_times, self.lags_t) self.Retreat_model_at_t = self.get_Rt_model(self.lags_t, self.ins_times) self.retreat_model_spline = IUS(self.ins_times, self.Retreat_model_at_t) self.iretreat_model_spline = self.retreat_model_spline.antiderivative() return
def __init__(self, times: np.ndarray, variable: np.ndarray): dt = np.diff(times) assert (dt > 0).all(), "times must be monotonically increasing" self._times = times self._variable = variable self._var_data_spline = IUS(self._times, self._variable) self._int_var_data_spline = self._var_data_spline.antiderivative() self._var2_data_spline = IUS(self._times, self._variable**2) self._int_var2_data_spline = self._var2_data_spline.antiderivative()
def __init__(self, times: np.ndarray, variable: np.ndarray): self._times = times self._variable = variable self._var_data_spline = IUS(self._times, self._variable) self._int_var_data_spline = self._var_data_spline.antiderivative() self._var2_data_spline = IUS(self._times, self._variable ** 2) self._int_var2_data_spline = self._var2_data_spline.antiderivative() self._var3_data_spline = IUS(self._times, self._variable ** 3) self._int_var3_data_spline = self._var3_data_spline.antiderivative()
def build_splines(self): """Build the splines needed for integrals over mass bins. """ lM_min, lM_max = self.l10M_bounds M_domain = np.logspace(lM_min - 1, lM_max + 1, num=500) sigmaM = np.array( [cc.sigmaMtophat(M, self.scale_factor) for M in M_domain]) self.sigmaM_spline = IUS(M_domain, sigmaM) ln_sig_inv_spline = IUS(M_domain, -np.log(sigmaM)) deriv_spline = ln_sig_inv_spline.derivative() self.deriv_spline = deriv_spline return
def dNdz_model(sample='qso', z_low=0.1, kind=1): if sample == 'qso': dNdz, z = np.loadtxt( f'/fs/ess/PHS0336/data/dr9v0.57.0/p38fnl/RF_g.txt').T dNdz_interp = IUS(z, dNdz) dNdz_interp.set_smoothing_factor(2.0) z_high = 4.0 nz_low = lambda z: z**kind * dNdz_interp(z_low) / z_low**kind nz_high = lambda z: np.exp(-z**1.65) * dNdz_interp(z_high) / np.exp( -z_high**1.65) z_g = np.linspace(0.0, 10.0, 500) dNdz_g = dNdz_interp(z_g) dNdz_g[(z_g < z_low)] = nz_low(z_g[z_g < z_low]) dNdz_g[(z_g > z_high)] = nz_high(z_g[z_g > z_high]) #plt.plot(z, dNdz, 'b--', lw=4, alpha=0.3) #plt.plot(z_g, dNdz_g, 'r-') # plt.semilogy() # plt.ylim(1.0e-8, 1.e3) return z_g, dNdz_g elif sample == 'lrg': zmin, zmax, dNdz = np.loadtxt( '/fs/ess/PHS0336/data/rongpu/sv3_lrg_dndz_denali.txt', usecols=(0, 1, 2), unpack=True) zmid = 0.5 * (zmin + zmax) dNdz_interp = IUS(zmid, dNdz, ext=1) dNdz_interp.set_smoothing_factor(2.0) z_g = np.linspace(0.0, 5.0, 500) dNdz_g = dNdz_interp(z_g) return z_g, dNdz_g elif sample == 'mock': z = np.arange(0.0, 3.0, 0.001) i_lim = 26. # Limiting i-band magnitude z0 = 0.0417 * i_lim - 0.744 Ngal = 46. * 100.31 * (i_lim - 25.) # Normalisation, galaxies/arcmin^2 pz = 1. / (2. * z0) * (z / z0)**2. * np.exp( -z / z0) # Redshift distribution, p(z) dNdz = Ngal * pz # Number density distribution return z, dNdz else: raise NotImplemented(f'{sample}')
def get_sf_rm(self, mode, m, capt_params, ri=0.99): ''' Get shock formation location from Eq. 7 of Ro&Matzner 2017 NB by default, the mode is deposited near the outer layers of the star unlike in Ro&Matzner where it is deposited deep inside of the star. xi is the initial radius of the Perturbation ''' Lmax=2.0*np.pi*self.rs**2.*self.rhos*self.cs**3. xs2,vs=self.get_mode_vel(mode, m, capt_params) ud=IUS(xs2, vs).derivative(1)(ri) Lmaxi=IUS(self.rs, Lmax)(ri) g=5./3. return self.rs, [IUS(self.rs, -ud*(g+1.)/2.*(Lmax/Lmaxi)**0.5/self.cs).integral(ri, rr) for rr in self.rs]
def __init__(self, h=0.67556, T0_cmb=2.7255, Omega0_b=0.0482754208891869, Omega0_cdm=0.26377065934278865, N_ur=None, m_ncdm=[0.06], P_k_max=10.0, P_z_max=100.0, sigma8=0.8225, gauge='synchronous', n_s=0.9667, nonlinear=False): # input parameters kw_cosmo = locals() kw_cosmo.pop('self') for kw, val in kw_cosmo.items(): print(f'{kw:10s}: {val}') sigma8 = kw_cosmo.pop('sigma8') cosmo = cosmology.Cosmology(**kw_cosmo).match(sigma8=sigma8) # --- cosmology calculators redshift = 0.0 delta_crit = 1.686 # critical overdensity for collapse from Press-Schechter DH = ( cosmo.H0 / cosmo.C ) # in units of h/Mpc, eq. 4 https://arxiv.org/pdf/astro-ph/9905116.pdf Omega0_m = cosmo.Omega0_m k_ = np.logspace(-10, 10, 10000) Plin_ = cosmology.LinearPower(cosmo, redshift, transfer='CLASS') # P(k) in (Mpc/h)^3 self.Plin = IUS(k_, Plin_(k_), ext=1) Tlin_ = cosmology.transfers.CLASS( cosmo, redshift) # T(k), normalized to one at k=0 tk_ = Tlin_(k_) is_good = np.isfinite(tk_) self.Tlin = IUS(k_[is_good], tk_[is_good], ext=1) self.Dlin = cosmo.scale_independent_growth_factor # D(z), normalized to one at z=0 self.f = cosmo.scale_independent_growth_rate # dlnD/dlna self.Dc = cosmo.comoving_distance self.h = cosmo.efunc self.inv_pi = 2.0 / np.pi # alpha_fnl: equation 2 of Mueller et al 2017 self.alpha_fnl = 3.0 * delta_crit * Omega0_m * (DH**2)
def build_C0_spline(max_log10_sigma=0., npt=100, ret_all=False, beta=4.): """ Generate a spline of C0 vs sigma values for the McQuinn formalism Args: max_log10_sigma (float, optional): npt (int, optional): ret_all (bool, optional): if True, return more items beta (float, optional): Returns: float or tuple: If ret_all, return f_C), sigmas, COs else return the spline """ sigmas = 10**np.linspace(-2, max_log10_sigma, npt) C0s = np.zeros_like(sigmas) # Loop for kk, sigma in enumerate(sigmas): # Minimize res = minimize_scalar(deviate1, args=(sigma, beta)) C0s[kk] = res.x # Spline f_C0 = IUS(sigmas, C0s) # Return if ret_all: return f_C0, sigmas, C0s else: return f_C0
def _init_cosmology(self, om_m=0.26, om_L=0.7, h=0.69, zmin=0.01, zmax=1.5, nbin=30): # 0.69 # 0.26 # theoretical mu self.z_grid = np.linspace(zmin, zmax, nbin) #self.z_grid = np.logspace(np.log10(zmin), np.log10(zmax), nbin) # logarithmic grid theory = Cosmology(om_m=om_m, om_L=om_L, h=h) self.mu_th = 5 * np.log10(np.vectorize(theory.DL)(self.z_grid)) + 25 # interpolate the theory on data points self.mu_th_spl = IUS(self.z_grid, self.mu_th) # guess self.mu_g_grid = self.mu_th self.mu_g_data = self.mu_th_spl(self.z_data) self.mu_g_data_t = self.mu_th_spl(self.z_data_t) # chi2 self.chi2 = [chi2(self.mu_g_data, self.mu_data, self.mu_err)] self.err = [chi2(self.mu_g_data_t, self.mu_data_t, self.mu_err_t)] self.baseline = [ chi2(np.mean(self.mu_data), self.mu_data, self.mu_err), chi2(np.mean(self.mu_data), self.mu_data_t, self.mu_err_t) ]
def get_args(i): Ms = np.array([]) bs = np.array([]) tbs = np.array([]) pd = np.array([]) pde = np.array([]) bes = np.array([]) icovs = np.array([]) boxes = np.array([]) snaps = np.array([]) cosmo, h, Omega_m = get_cosmo(i) hmf = mf_obj(i) k = np.logspace(-5, 1, num=1000) #Mpc^-1 kh = k/h nus = [] #sigma^2 for j in range(0,10): #snap z = zs[j] M, Mlo, Mhigh, b, be = np.loadtxt("/Users/tmcclintock/Data/linear_bias_test/TestBox%03d-combined_Z%d_DS50_linearbias.txt"%(i,j)).T M = np.ascontiguousarray(M) Mlo = np.ascontiguousarray(Mlo) Mhigh = np.ascontiguousarray(Mhigh) inds = Mhigh > 1e99 Mhigh[inds] = 1e16 p = np.array([cosmo.pk_lin(ki, z) for ki in k])*h**3 nu = ph.nu_at_M(M, kh, p, Omega_m) #Replace this part with the average bias Mbins = np.array([Mlo, Mhigh]).T n_bins = hmf.n_in_bins(Mbins, z) #Denominator Marr = np.logspace(np.log10(M[0]*0.98), 16, 1000) lMarr = np.log(Marr) nuarr = ph.nu_at_M(Marr, kh, p, Omega_m) dndlm = hmf.dndlM(Marr, z) b_n = dndlm * ct.bias.bias_at_nu(nuarr) b_n_spl = IUS(lMarr, b_n) lMbins = np.log(Mbins) tb = np.zeros_like(nu) for ind in range(len(tb)): tbi = quad(b_n_spl, lMbins[ind,0], lMbins[ind,1]) tbi2 = b_n_spl.integral(lMbins[ind,0], lMbins[ind,1]) #print tbi[0]/n_bins[ind], tbi2/n_bins[ind] tb[ind] = tbi[0] / n_bins[ind] #print b #exit() #print tb #print ct.bias.bias_at_nu(nu) #instantaneous tinker bias #tb = ct.bias.bias_at_nu(nu) #instantaneous tinker bias tbs = np.concatenate((tbs, tb)) Ms=np.concatenate((Ms, M)) bs=np.concatenate((bs, b)) bes=np.concatenate((bes, be)) nus = np.concatenate((nus, nu)) pd = np.concatenate((pd, (b-tb)/tb)) pde = np.concatenate((pde, be/tb)) boxes = np.concatenate((boxes, np.ones_like(M)*i)) snaps = np.concatenate((snaps, np.ones_like(M)*j)) return nus, bs, bes, Ms, tbs, pd, pde, boxes, snaps
def get_multiplicative_bias_prior(zi): #See McClintock et al. (2019) for details z, R, Re = np.loadtxt("../data/photoz_calibration/sci_correction.dat", unpack=True) delta_plus_1 = 1. / R dp1_unc = Re / R**2 dp1_spline = IUS(z, delta_plus_1) dp1e_spline = IUS(z, dp1_unc) dp1_z = dp1_spline(zi) dp1_var = dp1e_spline(zi)**2 #Shear m = 0.012 #Y1 value! TODO m_var = 0.013**2 #Y1 value! TODO Am_mean = dp1_z + m Am_var = dp1_var + m_var return Am_mean, Am_var
def log_integral(x1, x2, xs, ys): ''' Compute \int_{u1}^{u2} e^u y(u) du, where u is log(x), u1=log(x1), and u2=log(x2). y(u) is conputed from an interpolating spline constructed from xs and ys ''' us=np.log(xs) return IUS(us, ys*np.exp(us)).integral(np.log(x1), np.log(x2))
def __init__(self): dat_poly=np.genfromtxt(os.path.join(os.path.dirname(__file__), 'poly3.tsv')) self.R=u.Quantity(dat_poly[:,0]) self.Rho=u.Quantity(dat_poly[:,1]) self.mass=u.Quantity([IUS(self.R, 4.0*np.pi*self.R**2.*self.Rho).integral(self.R[0], rr) for rr in self.R]) self.cs=u.Quantity((0.85*(5./3.)*(self.Rho/self.Rho[0])**(1./3.))**0.5*(G*self.mass[-1]/self.R[-1])**0.5) self.P=u.Quantity(self.cs**2.*self.Rho/(5./3.))
def _unboxHermiteOptimal(self): #This is a special constructor that was built from an optimization routine Npoints = 5 x_herm = numpy.concatenate( (linspace(0, 0.3, Npoints), linspace(.3, 1, Npoints)[1:])) y_herm = numpy.array([ 0.0, 0.01950203, 0.0351703, 0.04887419, 0.06248457, 0.11138664, 0.21265207, 0.46874771, 1.0 ]) m_herm = self._cubic_mono_hermite_spline(x_herm, y_herm) interm_n = 100 #Construct inverse (xout, yout, dr) = self._buildHermite(x_herm, y_herm, interm_n) self.h_r = lambda L: self._hermite_spline_point( L, x_herm, y_herm, m_herm, 'point') self.dh_r = lambda L: self._hermite_spline_point( L, x_herm, y_herm, m_herm, 'der') self.h_a = lambda L: L self.dh_a = lambda L: 1 self.d2h_a = lambda L: 0 self.h_e = lambda L: L self.dh_e = lambda L: 1 self.d2h_e = lambda L: 0 self.h_r_inv = IUS(yout, xout) self.h_a_inv = lambda h: h self.h_e_inv = lambda h: h
def get_data(filename): # Make dataframe df = pd.read_csv(filename, names=["Wavelength", "Absorbance"], delimiter=",")[::-1] # Remove rows where we get NaN as an absorbance df = df.apply(pd.to_numeric, errors='raise') df = df.dropna() # We only care about the wavelengths between 400 and 700 nm. df = df[(df["Wavelength"] < 700) & (400 < df["Wavelength"])] # Smooth the absorbance data df["Absorbance"] = ss.savgol_filter(df["Absorbance"], window_length=9, polyorder=4) # An object which makes splines spline_maker = IUS(df["Wavelength"], df["Absorbance"]) # An object which calculates the derivative of those splines deriv_1 = spline_maker.derivative(n=1) deriv_2 = spline_maker.derivative(n=2) # Calculate the derivative at all of the splines df["First_derivative"] = deriv_1(df["Wavelength"]) df["Second_derivative"] = deriv_2(df["Wavelength"]) return df
def average_DMhalos(z, cosmo=Planck15, f_hot=0.75, rmax=1., logMmin=10.3, neval=10000, cumul=False): """ Average DM_halos term from halos along the sightline to an FRB Args: z (float): Redshift of the FRB cosmo (Cosmology): Cosmology in which the calculations are to be performed. f_hot (float, optional): Fraction of the halo baryons in diffuse phase. rmax (float, optional): Size of a halo in units of r200 logMmin (float, optional): Lowest mass halos to consider Cannot be much below 10.3 or the Halo code barfs The code deals with h^-1 factors, i.e. do not impose it yourself neval (int, optional): Number of redshift values between 0 and z the function is evaluated at. cumul (bool, optional): Return a cumulative evaluation? Returns: DM_halos (Quantity or Quantity array): One value if cumul=False else evaluated at a series of z zeval (ndarray): Evaluation redshifts if cumul=True """ zeval, dz = np.linspace(0, z, neval, retstep=True) # Electron number density in the universe ne_tot = ne_cosmic(zeval, cosmo=cosmo) # Diffuse gas mass fraction f_diff = f_diffuse(zeval, cosmo=cosmo) # Fraction of total mass in halos zvals = np.linspace(0, z, 20) fhalos = halos.frac_in_halos(zvals, Mlow=10**logMmin, Mhigh=1e16, rmax=rmax) fhalos_interp = IUS(zvals, fhalos)(zeval) # Electron number density in halos only ne_halos = ne_tot * fhalos_interp * f_hot / f_diff # Cosmology -- 2nd term is the (1+z) factor for DM denom = cosmo.H(zeval) * (1 + zeval) * (1 + zeval) # DM halos DM_halos = (constants.c * np.cumsum(ne_halos * dz / denom)).to('pc/cm**3') # Return if cumul: return DM_halos, zeval else: return DM_halos[-1]
def frac_in_halos(zvals, Mlow, Mhigh, rmax=1.): """ Calculate the fraction of dark matter in collapsed halos over a mass range and at a given redshift Note that the fraction of DM associated with these halos will be scaled down by an additional factor of f_diffuse Requires Aemulus HMF to be installed Args: zvals: ndarray Mlow: float In h^-1 units already so this will be applied for the halo mass function Mhigh: float In h^-1 units already rmax: float Extent of the halo in units of rvir Returns: ratios: ndarray rho_halo / rho_m """ hmfe = init_hmf() M = np.logspace(np.log10(Mlow * cosmo.h), np.log10(Mhigh * cosmo.h), num=1000) lM = np.log(M) ratios = [] for z in zvals: a = 1. / (1.0 + z) # scale factor # Setup #dndlM = np.array([hmfe.dndlnM(Mi, a)[0] for Mi in M]) dndlM = hmfe.dndlnM(M, z) M_spl = IUS(lM, M * dndlM) # Integrate rho_tot = M_spl.integral(np.log(Mlow * cosmo.h), np.log( Mhigh * cosmo.h)) * units.M_sun / units.Mpc**3 # Cosmology rho_M = cosmo.critical_density(z) * cosmo.Om(z) / ( 1 + z)**3 # Tinker calculations are all mass ratio = (rho_tot * cosmo.h**2 / rho_M).decompose() # ratios.append(ratio) ratios = np.array(ratios) # Boost halos if extend beyond rvir (homologous in mass, but constant concentration is an approx) if rmax != 1.: #from pyigm.cgm.models import ModifiedNFW c = 7.7 nfw = ModifiedNFW(c=c) M_ratio = nfw.fy_dm(rmax * nfw.c) / nfw.fy_dm(nfw.c) ratios *= M_ratio # Return return np.array(ratios)
def average_DMIGM(z, fb=1., rmax=1., neval=1000): """ Estimate DM_IGM in a cumulative fashion Args: z (float): Redshift for the evaluation fb (float, optional): Fraction of the cosmic baryons in a given halo 1 means halos have all of their alloted baryons to r200 rmax (float, optional): neval (int, optional): Number of redshift evaluations Returns: ndarray, Quantity """ # Redshifts zvals = np.linspace(0., z, 50) # Keep it cheap for fhalos dz_vals = zvals[1] - zvals[0] # Fraction of DM mass in halos fhalos = halos.frac_in_halos(zvals, 3e10, 1e16, rmax=rmax) # Fraction of mass in IGM fIGM = 1. - fhalos * fb # DM_cosmic DM_cosmic_cumul, zeval = average_DM(z, cumul=True, neval=neval) dzeval = zeval[1] - zeval[0] dDM_cosmic = DM_cosmic_cumul - np.roll(DM_cosmic_cumul, 1) dDM_cosmic[0] = dDM_cosmic[1] DM_interp = IUS(zeval, dDM_cosmic) dDM_IGM = DM_interp(zvals) * fIGM * dz_vals / dzeval dDM_cosm = DM_interp(zvals) * dz_vals / dzeval # Interpolate sub_DM_IGM = np.cumsum(dDM_IGM) f_IGM = IUS(zvals, sub_DM_IGM) # Evaluate DM_IGM = f_IGM(zeval) # Return return DM_IGM * units.pc / units.cm**2, zeval
def make_dndlM_spline(self): """Creates a spline for dndlM so that the integrals over mass bins are faster """ bounds = np.log(10**self.l10M_bounds) lM = np.linspace(bounds[0], bounds[1], num=100) dndlM = np.array([self.dndlM(lMi) for lMi in lM]) self.dndlM_spline = IUS(lM, dndlM) return lM, dndlM
def get_data(self): full_y = self.ds.get_data()[:,0] full_x = np.arange(full_y.shape[0]) non_nan_indexes = np.logical_not(np.isnan(full_y)) non_nan_x = np.copy(full_x[non_nan_indexes]) non_nan_y = full_y[non_nan_indexes] f = IUS(non_nan_x, non_nan_y, k=3) interped = f(full_x)[:,np.newaxis] return interped
def get_mode_info(mode_file, rs, dens, ms1, gs1): ''' Extract frequency and multipole order of the mode from GYRE output. Second argument is intepolation function, which contains the the density profile of the model. Only deals with adiabatic gyre output so far, so assume xis and omegas are real... mode_file -- file with info on stellar modes rs, dens, ms1, gs1--radii, densities, enclosed mass, gravitational acceleration (G menc(r)/r^2) ''' mode_dict={} mode_info=ascii.read(mode_file,header_start=1, data_end=3) mode_dict['omega']=float(mode_info['Re(omega)']) mode_dict['l']=float(mode_info['l']) dat_mode=ascii.read(mode_file, data_start=5, header_start=4) xs=dat_mode['x'] ##Make sure grid for mode file is consistent with that from stellar model. ##Take second radius in case first one is zero filt=(xs>=rs[1]) xs=xs[filt] rhos=IUS(rs, dens)(xs) ms=IUS(rs, ms1)(xs) gs=IUS(rs[1:], gs1[1:])(xs) aux=IUS(rs[1:], (rs[1:]**4./gs1[1:])).derivative(1)(xs) xi_r=dat_mode['Re(xi_r)'][filt] xi_h=dat_mode['Re(xi_h)'][filt] ##Normalizing the eigenmodes norm1=IUS(xs, rhos*xs**2.*xi_r**2.).integral(xs[0], xs[-1]) norm2=(mode_dict['l']+1.)*mode_dict['l']*IUS(xs, rhos*xs**2.*xi_h**2.).integral(xs[0], xs[-1]) norm=(norm1+norm2)**0.5 xi_r=xi_r/norm xi_h=xi_h/norm ##Standard expression for Mode overlap integral from Press&Teukolsky1977. if mode_dict['omega']>0.5: mode_dict['Q']=abs(IUS(xs, xs**2*rhos*mode_dict['l']*(xs**(mode_dict['l']-1.))*(xi_r+(mode_dict['l']+1.)*xi_h)).integral(xs[0], xs[-1])) ##Use eq. 78 from Ivanov, Papalaziou, Chernov 2013 for low frequencies as this is more numerically stable else: mode_dict['Q']=mode_dict['omega']**2.*abs(IUS(xs, xs**4.*rhos*(xi_r/gs+(xi_h/xs**3.)*aux)).integral(xs[0], xs[-1])) mode_dict['xi_r']=xi_r mode_dict['xi_h']=xi_h mode_dict['xs']=xs return mode_dict
def test_get_xt(self): time = np.linspace(0, 1e6, 1000) insolation = np.sin(np.radians(np.linspace(0, 360, 1000))) spline = np.linspace(0, 100, 1000) spline = IUS(time, insolation) csc_angle = np.radians(np.linspace(0, 360, 1000)) cot_angle = np.radians(np.linspace(0, 360, 1000)) constant = 1.0 slope = 1e-6 model = LinearInsolation(time, insolation, constant, slope) xt = model.get_xt(time, spline, cot_angle, csc_angle) assert (xt != np.nan).all() assert (xt != np.inf).all() assert np.size(xt) == np.size(time)
def deriv(self, degree: int) -> Tuple[np.array, np.array]: """Find the n-th derivative""" pH, volume = self.trim_values(self.ph, self.volume_titrant) # An object which makes splines spline_maker = IUS(volume, pH) # An object which calculates the derivative of those splines deriv_function = spline_maker.derivative(n=degree) # Calculate the derivative at all of the splines d = deriv_function(volume) return volume, d
def blanket_thickness(self, Nt=100, plot=False): bl, loop = {}, {} # read blanket for side in ['in', 'out']: bl[side], c = {}, {} for x in ['r', 'z']: c[x] = self.parts['Blanket'][side][x] r, z = geom.order(c['r'], c['z'], anti=True) r, z, l = geom.unique(r, z) # remove repeats bl[side]['r'], bl[side]['z'] = r, z loop[side] = {'r': IUS(l, r), 'z': IUS(l, z)} # interpolator def thickness(L, Lo, loop, norm): r = loop['in']['r'](Lo) + L[0] * norm['nr'](Lo) z = loop['in']['z'](Lo) + L[0] * norm['nz'](Lo) err = (r-loop['out']['r'](L[1]))**2+\ (z-loop['out']['z'](L[1]))**2 return err r, z = geom.unique(bl['in']['r'], bl['in']['z'])[:2] # remove repeats nr, nz, r, z = geom.normal(r, z) l = geom.length(r, z) norm = {'nr': IUS(l, nr), 'nz': IUS(l, nz)} # interpolator dt, Lo = np.zeros(Nt), np.linspace(0, 1, Nt) for i, lo in enumerate(Lo): L = minimize(thickness, [0, lo], method='L-BFGS-B', bounds=([0, 5], [0, 1]), args=(lo, loop, norm)).x dt[i] = np.sqrt((loop['in']['r'](lo) - loop['out']['r'](L[1]))**2 + (loop['in']['z'](lo) - loop['out']['z'](L[1]))**2) dt[i] = L[0] dt = savgol_filter(dt, 7, 2) # filter if plot: pl.plot(Lo, dt) return [np.min(dt), np.max(dt)]
def plot_bf(i, args, bfpath, savepath=None): cosmo, h, Omega_m, hmf = get_cosmo(i) params = np.loadtxt(bfpath) colors = [plt.get_cmap("seismic")(ci) for ci in np.linspace(1.0, 0.0, len(zs))] fig, ax = plt.subplots(2, sharex=True) for j in range(len(zs)): z = zs[j] M = args['Ms'][j] b = args['biases'][j] be = args['berrs'][j] nu = args['nus'][j] lMbins = args['lMbins'][j] lMarr = args['lMarr'] nuarr = args['nuarrs'][j] dndlM = args['dndlMs'][j] nbin = args['n_bins'][j] a1,a2,b1,b2,c1,c2 = model_swap(params, args, args['x'][j]) b_n = dndlM * bias._bias_at_nu_FREEPARAMS(nuarr,a1,a2,b1,b2,c1,c2) b_n_spl = IUS(lMarr, b_n) bmodel = np.array([quad(b_n_spl, lMbins[k,0], lMbins[k,1])[0]/nbin[k] for k in range(len(M))]) #bmodel = bias._bias_at_nu_FREEPARAMS(nu,a1,a2,b1,b2,c1,c2) ax[0].errorbar(M, b, be, c=colors[j], marker='.', ls='',label=r"$z=%.2f$"%z) ax[0].loglog(M, bmodel, ls='-', c=colors[j]) pd = (b-bmodel)/bmodel pde = be/bmodel ax[1].errorbar(M, pd, pde, c=colors[j]) ax[1].axhline(0, c='k', ls='--', zorder=-1) xlim = ax[1].get_xlim() ax[1].fill_between(xlim,-.01,.01, color='gray', alpha=0.4, zorder=-2) ax[1].set_xlim(xlim) ax[0].set_xscale('log') ax[0].legend(frameon=False, loc="upper right", fontsize=8) ax[1].set_xlabel(r"$M\ [{\rm M_\odot}/h]$") ax[1].set_ylabel(r"$(b_{\rm sim}-b_{\rm Fit})/b_{\rm Fit}$") ax[0].set_ylabel(r"$b(M)$") ax[0].set_yscale('linear') #ax[0].text(1e13, 4, "PRELIMINARY", color='r', fontsize=20, alpha=0.5) #ax[1].text(1e13, 0.02, "PRELIMINARY", color='r', fontsize=20, alpha=0.5) plt.subplots_adjust(hspace=0, bottom=0.15, left=0.15) if savepath: plt.gcf().savefig(savepath, dpi=300, bbox_inches='tight') else: plt.show() plt.clf()