def bisector(rv, ccf, low_high_cut = 0.1, figure_title = '', doplot = False, ccf_plot_file = '', showplot=False): # use the props from the CCF determination code # Could be per-order or with the mean #rv = props['RV_CCF'] #ccf = props['MEAN_CCF'] # get minima imin = int(np.argmin(ccf)) #print(imin,type(imin)) # get point where the derivative changes sign at the edge of the line # the bisector is ambiguous passed this poind width_blue = imin - np.max(np.where(np.gradient(ccf[:imin])>0)) #print(width_blue) width_red = np.min(np.where(np.gradient(ccf[imin:])<0)) #print(width_red) # get the width from the side of the center that reaches # that point first width = int(np.min([width_blue, width_red])) # set depth to zero ccf -= np.min(ccf) # set continuum to one ccf /= np.min( ccf[ [imin - width,imin + width] ]) # interpolate each side of the ccf slope at a range of depths depth = np.arange(low_high_cut,1-low_high_cut,0.001) # blue and red side of line g1 = (ccf[imin:imin - width:-1]>low_high_cut) & (ccf[imin:imin - width:-1]<(1-low_high_cut)) spline1 = ius(ccf[imin:imin - width:-1][g1],rv[imin:imin - width:-1 ][g1], k=2) g2 = (ccf[imin : imin + width]>low_high_cut) & (ccf[imin : imin + width]<(1-low_high_cut)) spline2 = ius(ccf[imin : imin + width][g2],rv[imin : imin + width][g2], k=2) # get midpoint bisector_position = (spline2(depth)+spline1(depth))/2 # get bisector widht width_ccf = (spline2(depth)-spline1(depth)) if doplot: # some nice plots plt.plot(rv[imin - width : imin+ width],ccf[imin - width : imin+ width],label = 'ccf') plt.plot(bisector_position,depth,label = 'bisector') plt.plot((bisector_position-np.mean(bisector_position))*100+np.mean(bisector_position),depth, label = 'bisector * 100', ) plt.legend() plt.title(figure_title) plt.xlabel('Velocity (km/s)') plt.ylabel('Depth') if ccf_plot_file !='': plt.savefig(ccf_plot_file) if showplot : plt.show() # define depth in the same way as Perryman, 0 is top, 1 is bottom return 1-depth, bisector_position, width_ccf
def set_cosmology(self, cosmo): self.cosmo_now = cosmo params = cosmo.get_cosmology() self.sM.set_cosmology(cosmo) self.sigs0 = self.sM.get_sigma_in_default_binning() Om = 1 - params[0, 2] dlnsdlnm = np.gradient(np.log(self.sigs0)) / \ np.gradient(np.log(self.Mlist)) self.f_to_num = -(Om * hmf_gp.rho_cr) * dlnsdlnm / self.Mlist**2 flag, params_out = cosmo_util.test_cosm_range(params, return_edges=True) if flag: self.coeff_table = (np.dot( self.gps.predict(np.atleast_2d(params_out)), self.eigdata) + self.ymean).reshape(21, 2) else: self.coeff_table = ( np.dot(self.gps.predict(np.atleast_2d(params)), self.eigdata) + self.ymean).reshape(21, 2) self.coeff_table[:, 0] /= 10 self.coeff_Anorm_spl = ius(-self.redshift_list, self.coeff_table[:, 0]) self.coeff_a_spl = ius(-self.redshift_list, self.coeff_table[:, 1])
def Mass_nu(emu, nu, z): # TODO: This does both interpolation and evaluation, could split up? # Import from scipy.interpolate import InterpolatedUnivariateSpline as ius # Options log_interp = log_interp_sigma # Should sigma(M) be interpolated logarithmically? # Get internal M vs sigma arrays Ms_internal = emu.massfunc.Mlist sig0s_internal = emu.massfunc.sigs0 sigs_internal = sig0s_internal * emu.Dgrowth_from_z(z) nus_internal = dc / sigs_internal # Make an interpolator for sigma(M) if log_interp: mass_interpolator = ius(nus_internal, np.log(Ms_internal)) else: mass_interpolator = ius(nus_internal, Ms_internal) # Get sigma(M) from the interpolator at the desired masses if log_interp: Mass = np.exp(mass_interpolator(nu)) else: Mass = mass_interpolator(nu) return Mass
def get_p_gg(self, k, redshift): """get_p_gg Compute galaxy power spectrum :math:`\\P_\mathrm{gg}(k)`. Args: k (numpy array): 3 dimensional separation in :math:`h^{-1}\mathrm{Mpc}` redshift (float): redshift at which the galaxies are located Returns: numpy array: galaxy power spectrum """ from scipy.interpolate import InterpolatedUnivariateSpline as ius self._check_update_redshift(redshift) self._compute_p_1hcs(redshift) self._compute_p_1hss(redshift) self._compute_p_2hcc(redshift) self._compute_p_2hcs(redshift) self._compute_p_2hss(redshift) p_tot_1h = 2. * self.p_1hcs + self.p_1hss p_tot_2h = self.p_2hcc + 2. * self.p_2hcs + self.p_2hss p_gg = ius(self.fftlog_1h.k, p_tot_1h)(k) + ius(self.fftlog_2h.k, p_tot_2h)(k) return p_gg
def get_ilpk(zz, mode='real'): '''return log-interpolated pk at redshift z(aa) for Hankel transform''' aa = 1 / (zz + 1) al, b1, b2 = alphad['%0.1f' % zz], b1lstd['%0.1f' % zz], b2lstd['%0.1f' % zz], pkd = np.loadtxt(dpath + "HI_bias_{:06.4f}.txt".format(aa))[1:, :] bb = pkd[1:6, 2].mean() print(1 + b1, bb, (1 + b1) / bb) if mode == 'real': kk, pk = pkd[:, 0], pkd[:, 2]**2 * pkd[:, 3] elif mode == 'red': pks = np.loadtxt(dpath + "HI_pks_1d_{:06.4f}.txt".format(aa))[1:, :] kk, pk = pks[:, 0], pks[:, 1] bbs = (pk / ius(pkd[:, 0], pkd[:, 3])(kk))**0.5 bb = bbs[1:6].mean() #pk *= bb**2/bbs**2 #on large scales, extend with b^2*P_lin klin, plin = np.loadtxt('../../data/pklin_{:06.4f}.txt'.format(aa), unpack=True) plin *= bb**2 ipklin = ius(klin, plin) kt = np.concatenate((klin[(klin < kk[0])], kk)) pt = np.concatenate((plin[(klin < kk[0])] * pk[0] / ipklin(kk[0]), pk)) #On small scales, truncate at k=1 pt = pt[kt < 1] kt = kt[kt < 1] ilpk = loginterp(kt, pt) return ilpk
def convolve(self, k, x, y): #FIXME most naive implementation, could do better with just about anything else for the integral #Do the N^2 operation, assume (probably bad) that not zero padding is fine #It would be better (for all N>100) to do the fft convolution A, B = ius(k, x, ext=1), ius(k, y, ext=1) N = len(k) res = np.zeros(N) for i in range(N): res[i] = np.trapz(k**2 * A(abs(k - k[i])) * B(k), x=k) / (2 * np.pi**2) return res
def __init__(self, parameters): NSProblem.__init__(self, parameters=parameters) self.prm['viscosity'] = 1. / self.prm['Re'] self.L = 30. f = open('../data/Re395/statistics_streamwise.txt') a = loadtxt(f, comments='%') sz = a.shape a2 = zeros((sz[0] + 2, 2)) a2[1:-1, :] = a[:, :2] a2[1:-1, 0] += 10. # Bump starts at x = 10 a2[-1, 0] = self.L self.bump = ius(a2[:, 0], a2[:, 1]) # Create bump-spline # Use Expressions for 'complicated' profiles self.inlet_velocity = { 'u': U0(self.bump), 'p': ('0'), 'up': UP0(self.bump) } # Otherwise just initialize to zero self.zero_velocity = Initdict(u=("0.0", "0.0"), p="0.0") self.mesh, self.boundaries = self.create_mesh_and_boundaries() self.prm['dt'] = self.timestep() transient = self.prm['time_integration'] == 'Transient' self.q0 = self.zero_velocity if transient else self.inlet_velocity
def get_p_gm(self, k, redshift): """get_p_gm Compute galaxy matter power spectrum P_gm. Args: k (numpy array): 2 dimensional projected separation in :math:`h^{-1}\mathrm{Mpc}` redshift (float): redshift at which the lens galaxies are located Returns: numpy array: excess surface density in :math:`h M_\odot \mathrm{pc}^{-2}` """ from scipy.interpolate import InterpolatedUnivariateSpline as ius self._check_update_redshift(redshift) self._compute_p_cen(redshift) self._compute_p_cen_off(redshift) self._compute_p_sat(redshift) p_tot = self.p_cen + self.p_cen_off + self.p_sat p_gm = ius(self.fftlog_1h.k, p_tot)(k) return p_gm ### ###
def ilogcdfnfw(c=7): '''Inverse cdf of nfw in log-scale ''' rr = np.logspace(-4, 0, 1000) cdf = cumnfw(rr, c=c) lrr, lcdf = np.log(rr), np.log(cdf) return ius(lcdf, lrr)
def derivativesFromSpline(df, objName='obj', xName='rs_au', tName='time'): """Calculate first and second derivatives of a colum in a DataFrame via splines. Parameters: ----------- df ... input dataframe objName ... name of individual object/trajectory in dataframe xName ... column name for dependent variable in spline interpolation tname ... column name for independent variable (such as time). Returns: -------- x,xdot,xddot ... numpy array, returns x,dx/dt,d^2x/dt^2 for all values of t in df """ i = 0 objlist = df[objName].unique() xdot = [] xddot = [] x = [] for o in objlist: dat = df[df[objName] == o] s = ius(dat[tName].values, dat[xName].values) for index, row in dat.iterrows(): x.append(s.derivatives(row[tName])[0]) xdot.append(s.derivatives(row[tName])[1]) xddot.append(s.derivatives(row[tName])[2]) return np.array(x), np.array(xdot), np.array(xddot)
def get(self, rs, redshift, logdens): xic = np.array([ rbs(-self.logdens_list, -self.redshift_list, self.pred_table[:, :, i])(-logdens, -redshift) for i in range(66) ]) return np.exp(ius(self.logrscale, xic, ext=3)(np.log(rs)))
def tospline(problem): """Store the results in a dictionary of splines and save to file. The channel solution is very often used to initialize other problems that have a VelocityInlet.""" NS_solver = problem.pdesystems['Navier-Stokes'] Turb_solver = problem.pdesystems['Turbulence model'] f = open( '../data/channel_' + problem.prm['turbulence_model'] + '_' + str(problem.prm['Re_tau']) + '.ius', 'w') N = 1000 xy = zeros(N) xy = zeros((N, 2)) xy[:, 1] = linspace(0., 1., 1000) # y-direction spl = {} for s in (NS_solver, Turb_solver): for name in s.names: vals = zeros((N, s.V[name].num_sub_spaces() or 1)) for i in range(N): getattr(s, name + '_').eval(vals[i, :], xy[i, :]) spl[name] = [] # Create spline for all components # Scalar has zero subspaces, hence the or for i in range(s.V[name].num_sub_spaces() or 1): spl[name].append(ius(xy[:, 1], vals[:, i])) cPickle.dump(spl, f) f.close() return spl
def set_cosmology(self, cosmo): cparams = cosmo.get_cosmology() self.ns = cparams[0, 4] As = np.exp(cparams[0, 3]) / 1e10 k0 = 0.05 h = np.sqrt( (cparams[0, 0] + cparams[0, 1] + 0.00064) / (1 - cparams[0, 2])) gp_rec = np.array([ self.gps[i].predict(self.ydata[:800, i], np.atleast_2d(cparams[0, :3]), return_cov=False)[0] for i in range(20) ]) tk_rec = np.exp( np.dot(gp_rec * self.ystd + self.yavg, self.eigdata) + self.ymean) if not np.isclose(cparams[0, 5], -1): growth_wcdm = _linearGrowth( cparams[0, 2], cparams[0, 5], 0.) / _linearGrowth( cparams[0, 2], cparams[0, 5], 1000.) growth_lcdm = _linearGrowth(cparams[0, 2], -1., 0.) / _linearGrowth( cparams[0, 2], -1., 1000.) tk_rec *= growth_wcdm / growth_lcdm pzeta = (2.*np.pi**2)/self.klist**3 * As * \ (self.klist/(k0/h))**(self.ns-1.) self.pred_table = np.log(pzeta * tk_rec**2) self.pklin_spl = ius(self.logklist, self.pred_table, ext=3)
def create_boundaries(self): # Define the spline for the heart beat self.inflow_t_spline = ius(MCAtime, MCAval) # Preassemble normal vector on inlet n = self.n = FacetNormal(self.mesh) self.normal = [ assemble(-n[i] * ds(4), mesh=self.mesh) for i in range(3) ] # Area of inlet self.A0 = assemble(Constant(1.) * ds(4), mesh=self.mesh) # Create dictionary used for Dirichlet inlet conditions. Values are assigned in prepare self.inflow = { 'u': Constant((0, 0, 0)), 'u0': Constant(0), 'u1': Constant(0), 'u2': Constant(0) } # Pressures on outlets are specified by DirichletBCs self.p_out1 = Constant(0) # Specify the boundary subdomains and hook up dictionaries for DirichletBCs walls = MeshSubDomain(3, 'Wall') inlet = MeshSubDomain(4, 'VelocityInlet', self.inflow) pressure1 = MeshSubDomain(5, 'ConstantPressure', {'p': self.p_out1}) return [walls, inlet, pressure1]
def mass_avg(emu, Mmin, Mmax, z, pow=1): ''' Calculate the average halo mass between two limits, weighted by the halo mass function [Msun/h] ''' from scipy.interpolate import InterpolatedUnivariateSpline as ius from scipy.integrate import quad # Parameters epsabs = 1e-5 # Integration accuracy # Construct an interpolator for n(M) (or dn/dM) from the emulator internals Ms = emu.massfunc.Mlist dndM = emu.massfunc.get_dndM(z) log_dndM_interp = ius(np.log(Ms), np.log(dndM), ext='extrapolate') # Number density of haloes in the mass range n = ndenshalo(emu, Mmin, Mmax, z) # Integrate to get the average mass Mav, _ = quad(lambda M: (M**pow) * np.exp(log_dndM_interp(np.log(M))), Mmin, Mmax, epsabs=epsabs) return Mav / n
def wp(self, rp, pi=np.linspace(0, 100, 100 + 1), rMin=0.1, wantGrad=False): "FIXME: Lazy copy from AutoCorrelator - should make this function accessible by both. - general correlator class..." """Projected correlation function. Parameters: ----------- rp: array (float) 2D abscissa values for wp pi_bins: array (float) Array must be of size that divides evenly into r - projection window, tophat for now wantGrad : boolean,optional Whether to return the function value, or the tuple (val,grad). Returns: ---------- (array (float), array (float), [array (float)]) projected radius rp, projected correlation function wp, gradient if wanted """ if (wantGrad): wp_grad = np.zeros((len(rp), len(self.params))) xir, grad_xir = self.Xi(wantGrad=wantGrad) else: xir = self.Xi(wantGrad=wantGrad) dpi = pi[1] - pi[0] #bin width wp = np.zeros(len(rp)) for i in range(len(wp)): rev = np.sqrt(rp[i]**2 + pi**2) wp[i] = 2 * ius(rev, xir(rev) / np.sqrt(1 - (rp[i] / (rev + rMin))**2)).integral( rev.min(), rev.max()) if (wantGrad): wp_grad[i] = 2 * ius( rev, grad_xir(rev) / np.sqrt(1 - (rp[i] / (rev + rMin))**2)).integral( rev.min(), rev.max()) if (wantGrad): return wp, wp_grad else: return wp
def get_nhalo_tinker(self, Mmin, Mmax, vol, redshift): if Mmax > 1e16: Mmax = 1e16 dndM = self.get_dndM_tinker(redshift) dndM_interp = ius(np.log(self.Mlist), np.log(dndM)) return vol * integrate.quad( lambda t: np.exp(dndM_interp(np.log(t))), Mmin, Mmax, epsabs=1e-5)[0]
def _make_psfs(self): """ Produces PSF arrays""" self.psf2D = self.models[self.psffunct](self.rr, *self.psf) * \ self.dr * self.dr self.psf2D /= np.sum(self.psf2D) self.psf1D = ius(self.rr.diagonal()[self.rsize:], self.psf2D.diagonal()[self.rsize:]) self.fft_psf2D = np.fft.fft2(self.psf2D) return
def set_cosmology(self, cosmo): self.cosmo_now = cosmo cpara = cosmo.get_cosmology() self.coeff_rec = np.dot(self.gps.predict(np.atleast_2d(cpara)), self.eigdata).reshape(21, 13, 3) self.coeff_rec_dm = np.dot(self.gps_dm.predict(np.atleast_2d(cpara)), self.eigdata_dm).reshape(21, 2) self.sd0 = self.sd.get(cosmo) # self.D0s = np.array([cosmo.Dgrowth_from_z(z) for z in self.redshift_list]) self.coeff1_spline = rbs(-self.redshift_list, -self.logdens_list, self.coeff_rec[:, :, 0]) self.coeff2_spline = rbs(-self.redshift_list, -self.logdens_list, self.coeff_rec[:, :, 1]) self.coeff3_spline = rbs(-self.redshift_list, -self.logdens_list, self.coeff_rec[:, :, 2]) self.coeff2_spline_dm = ius(-self.redshift_list, self.coeff_rec_dm[:, 0]) self.coeff3_spline_dm = ius(-self.redshift_list, self.coeff_rec_dm[:, 1])
def dens_to_mass(self, dens, redshift, nint=20, integration="quad"): mlist = np.linspace(12., 15.95, nint) dlist = np.log( np.array([ self.mass_to_dens(10**mlist[i], redshift, integration=integration) for i in range(nint) ])) d_to_m_interp = ius(-dlist, mlist) return 10**d_to_m_interp(-np.log(dens))
def make_omHI_plot(fname, fsize=12): """Does the work of making the distribution figure.""" zlist = [2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0] clist = ['b', 'c', 'g', 'm', 'r'] # Now make the figure. fig, axis = plt.subplots(figsize=(6, 5)) # Read in the data and convert to "normal" OmegaHI convention. dd = np.loadtxt("../../data/omega_HI_obs.txt") #Ez = np.sqrt( 0.3*(1+dd[:,0])**3+0.7 ) #axis.errorbar(dd[:,0],1e-3*dd[:,1]/Ez**2,yerr=1e-3*dd[:,2]/Ez**2,\ # fmt='s',mfc='None') axis.errorbar(dd[:, 0], 1e-3 * dd[:, 1], yerr=1e-3 * dd[:, 2], fmt='s', mfc='None', color='m') # Plot the fit line. zz = np.linspace(0, 7, 100) Ez = np.sqrt(0.3 * (1 + zz)**3 + 0.7) axis.plot(zz, 4e-4 * (1 + zz)**0.6, 'k-') #for im, model in enumerate(['ModelA', 'ModelB', 'ModelC']): for im, model in enumerate(models): dpath = '../../data/outputs/%s/%s/' % (suff, model) omz = [] for iz, zz in enumerate(zlist): # Read the data from file. aa = 1.0 / (1.0 + zz) omHI = np.loadtxt(dpath + "HI_dist_{:06.4f}.txt".format(aa)).T omHI = (omHI[1] * omHI[2]).sum() / bs**3 / 27.754e10 omHI *= (1 + zz)**3 if iz == 0: axis.plot(zz, omHI, 'C%do' % im, label=model) else: axis.plot(zz, omHI, 'C%do' % im) omz.append(omHI) ss = ius(zlist, omz) axis.plot(np.linspace(2, 6, 100), ss(np.linspace(2, 6, 100)), 'C%d' % im) axis.set_yscale('log') axis.legend(fontsize=fsize) for tick in axis.xaxis.get_major_ticks(): tick.label.set_fontsize(fsize) for tick in axis.yaxis.get_major_ticks(): tick.label.set_fontsize(fsize) # Put on some more labels. axis.set_xlabel(r'$z$') axis.set_ylabel(r'$\Omega_{HI}$') # and finish up. plt.tight_layout() plt.savefig(fname)
def loginterp(x, y, yint = None, side = "both", lorder = 15, rorder = 15, lp = 1, rp = -1, \ ldx = 1e-6, rdx = 1e-6, k=5): if yint is None: yint = ius(x, y, k=k) if side == "both": side = "lr" l = lp r = rp lneff, rneff = 0, 0 niter = 0 while (lneff <= 0) or (lneff > 1): lneff = derivative(yint, x[l], dx=x[l] * ldx, order=lorder) * x[l] / y[l] l += 1 if niter > 100: continue print('Left slope = %0.3f at point ' % lneff, l) niter = 0 while (rneff < -3) or (rneff > -2): rneff = derivative(yint, x[r], dx=x[r] * rdx, order=rorder) * x[r] / y[r] r -= 1 if niter > 100: continue print('Rigth slope = %0.3f at point ' % rneff, r) xl = np.logspace(-18, np.log10(x[l]), 10**6.) xr = np.logspace(np.log10(x[r]), 10., 10**6.) yl = y[l] * (xl / x[l])**lneff yr = y[r] * (xr / x[r])**rneff xint = x[l + 1:r].copy() yint = y[l + 1:r].copy() if side.find("l") > -1: xint = np.concatenate((xl, xint)) yint = np.concatenate((yl, yint)) if side.find("r") > -1: xint = np.concatenate((xint, xr)) yint = np.concatenate((yint, yr)) yint2 = ius(xint, yint, k=k) return yint2
def wave2wave(e2ds_data_input, wave1, wave2): # transform e2ds data from one wavelength grid to another. e2ds_data = np.array(e2ds_data_input) for iord in range(49): keep = np.isfinite(e2ds_data[iord]) spl = ius(wave1[iord][keep],e2ds_data[iord][keep],k=3, ext=1) e2ds_data[iord][keep] = spl(wave2[iord][keep]) return e2ds_data
def fast_med(vect,w): # # inputs : vect -> vector to be median-filtered # w -> width of the filtering. Needs to be much shorter than # the length of vect # # performs a fast median filter for a box width that is too long to # be used with the normal numpy median filter. # The code performs a 'true' median with numpy, but does not # shift by 1 pixel as would be done with a true boxcar. # It moves by 1/2 of the width and splines in between. # # index of points along vector index = np.arange(len(vect),dtype=float) # index only on non-nans, all others are set to nans. # this ensures that the splining is properly centered if there is a # big bunch of NaNs on a width close to w index[np.isfinite(vect)==False]=np.nan # reshaping the vector in a form so that we can use the axis # keyword to do the job of a running boxcar. For a 1000-long vect and w=10 # this would be equivalent to reformating into a 100x10 array and then taking # the median with axis=1. # This is the same a taking a running median with a size of 10, and getting # the value every 10 pixels y1 = np.nanmedian(np.reshape( vect[0:w*(len(vect)//w)],[len(vect)//w,w]),axis=1) # same but with an offset of 0.5*w y2 = np.nanmedian(np.reshape( (np.roll(vect,w//2))[0:w*(len(vect)//w)],[len(vect)//w,w]),axis=1) # same median as for the vect value, but for the position along vect x1 = np.nanmedian(np.reshape( index[0:w*(len(vect)//w)],[len(vect)//w,w]),axis=1) x2 = np.nanmedian(np.reshape( (np.roll(index,w//2))[0:w*(len(vect)//w)],[len(vect)//w,w]),axis=1) # append the median-binned at each w*integer with w*(integer+0.5) x=np.append(x1,x2) y=np.append(y1,y2) ind = np.argsort(x) # get the binned vectors in order of index x=x[ind] y=y[ind] # remove NaNs. There may be stretches of vect larger than w that are full # of NaNs. We also use np.roll to remove points of identical x keep = np.isfinite(x) & (x != np.roll(x,1)) & np.isfinite(y) x=x[keep] y=y[keep] # spline the whole thing onto the vect grid spline = ius(x,y,k=2,ext=1) med_filt_vect = spline( np.arange(len(vect),dtype=float)) med_filt_vect[np.isfinite(vect) == False]=np.nan #output median-filtered vector return med_filt_vect
def _set_cosmology_param(self, cparams): gp_rec = np.array([self.gps[i].predict(self.ydata[:800, i], np.atleast_2d( cparams[[0, 1, 2, 4]]), return_cov=False)[0] for i in range(4)]) self.pred_table = np.sqrt(np.exp(cparams[3]) / self.As_fid * np.exp( np.dot(gp_rec*self.ystd+self.yavg, self.eigdata) + self.ymean)) if not np.isclose(cparams[5], -1): growth_wcdm = _linearGrowth( cparams[2], cparams[5], 0.)/_linearGrowth(cparams[2], cparams[5], 1000.) growth_lcdm = _linearGrowth( cparams[2], -1., 0.)/_linearGrowth(cparams[2], -1., 1000.) self.pred_table *= growth_wcdm/growth_lcdm self.sigma_M = ius(self.Mlist, self.pred_table)
def extrapolate(xvals: np.ndarray, yvals: np.ndarray, x: float, grouping: int = 5, order: int = 3): """Given equal-length arrays xvals and yvals, with the xvals in ascending order, produce an interpolated or extrapolated estimate for y at corresponding x. If there are enough points to use grouping to smooth out noise in the yvals, average over consecutive points up to groups of size grouping. """ assert len(xvals) == len(yvals) n = len(xvals) if n == 1: return yvals[0] if n == 0: raise IndexError # Do we have enough points to form (order+1) groups of size # grouping? while True: points = grouping * (order + 1) if points <= n: break if order > 1: order -= 1 elif grouping > 1: grouping -= 1 else: break if grouping > 1: pts = grouping * (order + 1) for array in (xvals, yvals): if x <= xvals[0]: tmp = array[:pts] else: tmp = array[-pts:] tmp = np.mean(np.reshape(tmp, (grouping, -1)), axis=1) if array == xvals: xvals = tmp else: yvals = tmp try: spline = ius(xvals, yvals, k=order) return float(spline(x)) except Exception as eeps: print(eeps) return yvals[0] # ???
def sigma_M(emu): ''' Create an interpolator for sigma(M) TODO: Attach this to emu class? ''' from scipy.interpolate import InterpolatedUnivariateSpline as ius log_interp = log_interp_sigma # Should sigma(M) be interpolated logarithmically? # Get internal M vs sigma arrays Ms_internal = emu.massfunc.Mlist sigs_internal = emu.massfunc.sigs0 g = emu.Dgrowth_from_z # This is a function # Make an interpolator for sigma(M) if log_interp: sigma_interpolator = ius(np.log(Ms_internal), np.log(sigs_internal), ext='extrapolate') else: sigma_interpolator = ius(Ms_internal, sigs_internal, ext='extrapolate') return lambda M, z: g(z) * sigma_interpolator(M)
def running_rms(sp1): sp1b = np.zeros(4096)+np.nan sp1b[4:-4] = sp1 with warnings.catch_warnings(record=True) as _: b1 = np.nanpercentile(np.reshape(sp1b, [16, 256]),[16,84], axis=1) rms = (b1[1]-b1[0])/2 index = np.arange(16)*256+128 keep = np.isfinite(rms) index = index[keep] rms = rms[keep] return ius(index,rms,k=2,ext=3)(np.arange(len(sp1)))
def psfconvolve(self, model1D_unc, model2D_unc): """ Returns a PSF convolved profile. """ model2D = np.fft.ifft2(np.fft.fft2(model2D_unc) * self.fft_psf2D).real model2D = np.fft.fftshift(model2D) model1D = np.column_stack((self.rr.diagonal(), model2D.diagonal())) index = np.where(model1D[:,0] == np.min(model1D[:,0]))[0][0] x, y = model1D[index:].T s = ius(x, y) rbox = x[-1] / np.sqrt(2) profile = model1D_unc profile[np.where(self.sma<rbox)] = s(self.sma[np.where(self.sma<rbox)]) return profile
def ISI_from_poisson(times, log=False, bw_PSTH=BW_PSTH, window=WINDOW, step=STEP, total_times=(0, 2.5), res=500, res_2=40, **kwargs): start, end = total_times time_bins = generate_time_bins(start, end, window=window, step=step) PSTH_func = PSTH(times, bw_PSTH=bw_PSTH, mirror=True, trial_time=total_times, res=res) delta_1 = (end - start) / (res - 1.) PSTH_list = [PSTH_func(y) for y in numpy.linspace(start, end, res)] int_firing_list = cumtrapz(PSTH_list, dx=delta_1) def prob(ISI, a, b): start_bin = int(a / delta_1) end_bin = int(b / delta_1) step = int(ISI / delta_1) Y = [PSTH_list[i] * PSTH_list[i + step] * numpy.exp(-int_firing_list[i + step] + int_firing_list[i]) for i in range(start_bin, end_bin - step)] value = trapz(Y, dx=delta_1) * ISI return value #num_trials = len(times) times = flatten(times) if log: ISI_short = -3. ISI_long = numpy.log10(window) else: ISI_short = .001 ISI_long = window X = numpy.linspace(ISI_short, ISI_long, res_2) delta_2 = (ISI_long - ISI_short) / (res_2 - 1.) prob_dict = {} for i, time_bin in enumerate(time_bins): if log: Y = numpy.array([prob(10**log_ISI, time_bin[0], time_bin[1]) * 10**log_ISI for log_ISI in X]) else: Y = numpy.array([prob(ISI, time_bin[0], time_bin[1]) for ISI in X]) norm = trapz(Y, dx=delta_2) Y = Y / norm prob_dict[tuple(time_bin)] = ius(X, Y) def prob_time_wrapper(ISI, time): try: value = prob_dict[current_bin(time, time_bins)](ISI) if value > 0: return(value) else: return(numpy.nan) except: return(numpy.nan) return prob_time_wrapper
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 get_dndM_mass(emu, Ms, z): ''' Return an array of n(M) (dn/dM in Dark Quest notation) at user-specified halo masses Extrapolates if necessary, which is perhaps dangerous ''' from scipy.interpolate import InterpolatedUnivariateSpline as ius # Construct an interpolator for n(M) (or dn/dM) from the emulator internals Ms = emu.massfunc.Mlist dndM = emu.massfunc.get_dndM(z) dndM_interp = ius(np.log(Ms), np.log(dndM), ext='extrapolate') # Evaluate the interpolator at the desired mass points return np.exp(dndM_interp(np.log(Ms)))
def fit_spline(coords,wvln,flux): sx,sy=np.array([]),np.array([]) for i in range(len(coords)): if coords[i][0] < 1.1: #hacky bug fix; make boolean? sx=np.append(sx,np.nan) sy=np.append(sy,np.nan) else: sx=np.append(sx,find_nearest(wvln, coords[i][0])) ind = np.where(wvln == sx[i]) sy=np.append(sy,flux[ind]) gv = np.isfinite(sy) sx,sy=sx[gv],sy[gv] sx=np.hstack((sx,wf)) sy=np.hstack((sy,nf)) indz = np.argsort(sx) sx,sy = sx[indz],sy[indz] # splfit=interpolate.splrep(sx,sy,s=0.7) #default deg=3 # cont = interpolate.splev(wvln,splfit) splfit = ius(sx, sy, k=3) cont = splfit(wvln) return cont, sx, sy
def match_x(ref_x, x_array, y_array): temp = ius(x_array, y_array) new_y = temp(ref_x) return new_y