def make_lightcone(nu_size, N, spatial_spacing): ## nu_size: integer - size of the frequency axis of lightcone ## N: integer - size of the boxes used to produce the lightcone ## spatial_spacing: 1D 3 entries array - spatial spacing of the boxes #### Initial and final frequency - choose them based on the box you have nu_i = 200 # with units nu_f = 100 # with units nu_spacing = -(nu_f - nu_i) / nu_size lightcone = np.zeros((N, N, nu_size)) nu_emitted = 1420 for layer in range(nu_size + 1): nu = nu_spacing * (layer) + nu_f z_given_nu = nu_emitted / nu - 1 zi = nu_emitted / (nu_i) - 1 com_dist_z = cosmo.comoving_distance(z_given_nu).value com_dist_zi = cosmo.comoving_distance(zi).value intZ = int(z_given_nu - 0.5) #print(intZ) data, redshift = data_library(np.array([intZ, 13]), N) red1 = redshift[0] red2 = redshift[1] loc_layer = int((com_dist_z - com_dist_zi) // spatial_spacing) if loc_layer >= N: while loc_layer >= N: loc_layer -= N #print(red1,red2) lightcone[:, :, layer - 1] = (data[1, loc_layer] - data[0, loc_layer]) * ( (z_given_nu - red1) / (red2 - red1)) + data[1, loc_layer] return lightcone
def get_radii(self, z_new): #gets you the new radii for any redshift #radii_new = (1+z_new)*comdis(z_obs)*radii/((1+z_obs)*comdis(z_new)) radii_new = ( (1 + z_new) * cosmo.comoving_distance(self.z) * self.radii) / ( (1 + self.z) * cosmo.comoving_distance(z_new)) return np.array(radii_new)
def get_ksz_snr_survey(zs, dndz, zedges, Cls, fsky, Ngals, bs=None, sigz=None): """ Get the total kSZ SNR from survey specifications. Provide the redshift distribution through (zs,dndz) Divide into "boxes" by specifying the redshift bin edges. This allows the survey overlap volumes in each bin to be computed from the overlap sky fraction fsky. Provide the total CMB+foreground+noise power in Cls. Provide sigma_z/(1+z) if this is a photometric survey. Provide the total number of galaxies in the overlap region in Ngals. Provide the galaxy biases in each bin in bs. """ from astropy.cosmology import WMAP9 as cosmo nbins = len(zedges) - 1 if not (bs is None): if len(bs) != nbins: raise Exception vols_gpc3 = [] ngals_mpc3 = [] snrs = [] zcents = [] tdndz = np.trapz(dndz, zs) bgs = [] for i in range(nbins): # Calculate bin volumes in Gpc3 zmin = zedges[i] zmax = zedges[i + 1] zcent = (zmax + zmin) / 2. chimin = cosmo.comoving_distance(zmin).value chimax = cosmo.comoving_distance(zmax).value vols_gpc3.append(fsky * (4. / 3.) * np.pi * (chimax**3. - chimin**3.) / 1e9) # Calculate comoving number densities sel = np.logical_and(zs > zmin, zs <= zmax) fracz = np.trapz(dndz[sel], zs[sel]) / tdndz Ng = Ngals * fracz ngals_mpc3.append(Ng / (vols_gpc3[i] * 1e9)) # Calculate SNRs snr, fksz = get_ksz_snr(vols_gpc3[i], zcent, ngals_mpc3[i], Cls, bs[i] if not (bs is None) else None, sigz=sigz) bgs.append(fksz.bgs[0]) snrs.append(snr) zcents.append(zcent) snrs = np.asarray(snrs) totsnr = np.sqrt(np.sum(snrs**2.)) return vols_gpc3, ngals_mpc3, zcents, bgs, snrs, totsnr
def build_light_cone(fileglob, zs=np.array([6, 6.5, 7]), boxtype='delta_T'): zs = np.array(zs) files = glob(fileglob) zind = {'delta_T': 5, 'Ts_z': 1, 'xH_': 2, 'deltax': 3} zsim = [] dims = [] lengths = [] files_keep = [] for f in files: if not os.path.basename(f).startswith(boxtype): if not 'updated_smoothed_' + boxtype in os.path.basename(f): continue files_keep.append(f) parms = os.path.basename(f).split('_') zsim.append(np.float(parms[zind[boxtype]][1:])) # redshifts dims.append(np.int(parms[-2])) # dim of box lengths.append(np.float(parms[-1][0:-3])) # length in Mpc files = files_keep if (np.max(np.diff(dims)) > 0) or (np.max(np.diff(lengths)) > 0): raise(ValueError('Boxes are not all the same size')) if (np.max(zs) > np.max(zsim)) or (np.min(zs) < np.min(zsim)): raise(ValueError('Requested redshifts outside range of sim.')) order = np.argsort(zsim) files = [files[i] for i in order] zsim = np.array([zsim[i] for i in order]) zsim0 = zsim[0] dim = dims[0] length = lengths[0] dx = length / dim lightcube = np.zeros((dim, dim, len(zs)), dtype=np.float32) Ds = cosmo.comoving_distance(zs).value - cosmo.comoving_distance(zsim0).value pix1 = map(int, np.floor(Ds / dx) % dim) wp1 = Ds / dx - np.floor(Ds / dx) pix2 = map(int, np.ceil(Ds / dx) % dim) wp2 = 1 - wp1 box1 = [np.argmax(zsim[zsim <= z]) for z in zs] box2 = [i + 1 for i in box1] wb2 = (zs - zsim[box1]) / (zsim[box2] - zsim[box1]) wb1 = (zsim[box2] - zs) / (zsim[box2] - zsim[box1]) for i, z in enumerate(zs): data = np.fromfile(files[box1[i]], dtype=np.float32) data = data.reshape((dim, dim, dim)) slice11 = data[:, :, pix1[i]] slice12 = data[:, :, pix2[i]] data = np.fromfile(files[box2[i]], dtype=np.float32) data = data.reshape((dim, dim, dim)) slice21 = data[:, :, pix1[i]] slice22 = data[:, :, pix2[i]] lightcube[:, :, i] = (slice11 * wb1[i] * wp1[i] + slice12 * wb1[i] * wp2[i] + slice21 * wb2[i] * wp1[i] + slice21 * wb2[i] * wp2[i]) return lightcube
def verify_update(sky_obj): """ Check that the frequencies/redshifts/distances are consistent. If healpix, check that Npix/hpx_inds/Nside are consistent """ if sky_obj.shell is not None: Nside = sky_obj.Nside hpx_inds = sky_obj.hpx_inds Npix = sky_obj.Npix if Npix == 12*Nside**2: nt.assert_true(all(hpx_inds == np.arange(Npix))) else: nt.assert_true(Npix == hpx_inds.size) if sky_obj.freqs is not None: freqs = sky_obj.freqs Nfreq = sky_obj.Nfreq Z = sky_obj.Z r_mpc = sky_obj.r_mpc Zcheck = 1420./freqs - 1. Rcheck = WMAP9.comoving_distance(Zcheck).to("Mpc").value nt.assert_true(all(Zcheck == Zcheck)) nt.assert_true(all(Rcheck == Rcheck)) print sky_obj.updated nt.assert_true(len(sky_obj.updated) == 0) #The updated list should be cleared
def test_gaussian_box_pyramid(): """ Gaussian box estimated using pyramid method. """ N = 256 #Vox per side L = 300. #Mpc sig = 2.0 mu = 0.0 box = np.random.normal(mu, sig, (N, N, N)) ## Unconventional approach, but start with equal distances and go to redshifts r0 = WMAP9.comoving_distance(6.0).to("Mpc").value r_mpc = np.linspace(r0, r0 + L, N) def comov_dist(z): return WMAP9.comoving_distance(z).to("Mpc").value Z = np.array([z_at_value(comov_dist, r, zmin=5.0) for r in r_mpc]) angular_extent = 300 / np.mean(r_mpc) # 300 Mpc box at this distance (kbins, pk), dV = pspec_funcs.box_pyramid_pspec(box, angular_extent, r_mpc, Z, cosmo=True, return_dV=True) import pylab as pl pl.plot(kbins, pk) print np.sqrt(np.var(dV)) pl.axhline(y=sig**2 * np.mean(dV)) pl.show()
def update(self): """ Make Z, freq, healpix params, and rectilinear params consistent. Assume that whatever parameter was just changed has priority over others. If two parameters from the same group change at the same time, confirm that they're consistent. """ hpx_params = ['Nside', 'Npix', 'shell', 'hpx_inds'] z_params = ['Z', 'freqs', 'Nfreq', 'r_mpc'] r_params = ['L', 'N', 'box'] ud = np.unique(self.updated) for p in ud: if p == 'boxes': if self.box == None: self.box = self.boxes[0] if p == 'freqs': self.Z = 1420. / self.freqs - 1. self.r_mpc = cosmo.comoving_distance(self.Z).to("Mpc").value self.Nfreq = self.freqs.size if p == 'Nside': if self.Npix is None: self.Npix = hp.nside2npix(self.Nside) if self.hpx_inds is None: self.hpx_inds = np.arange(self.Npix) if p == 'box': self.N = self.box.shape[0] if p == 'Nside': if 'hpx_inds' not in ud: if 'Npix' not in ud: self.Npix = hp.nside2npix(self.Nside) self.hpx_inds = np.arange(self.Npix) if p == 'hpx_inds': self.Npix = self.hpx_inds.size self.updated = []
def to_galacto_centric(long, lat, redshift): distance = cosmo.comoving_distance(redshift) sc = SkyCoord(l=long * u.degree, b=lat * u.degree, distance=distance, frame='galactic') gc = sc.transform_to(Galactocentric) return [gc.x.value, gc.y.value, gc.z.value]
def max_dis_deg(self): ''' 150kpc ~= degree ''' dis = cosmo.comoving_distance(self.m_z) # Mpc r = 0.15 / dis.value self.max_r = r2arcsec(r) # degree return self.max_r
def comoving_radial_length(z, dnu): """ What is the comoving radial length for a given dnu? """ nu0 = 1420. / (z + 1) - dnu / 2. nu1 = nu0 + dnu z0, z1 = 1420. / nu0 - 1, 1420. / nu1 - 1 L = abs(np.diff(cosmo.comoving_distance([z0, z1]).value)[0]) return L
def deg2com(p): #degree + redshift 3D coordinates ra_r = np.radians(p[0]) dec_r = np.radians(p[1]) z = p[2] dc_z = cosmo.comoving_distance(z).value xp = dc_z * np.cos(ra_r) * np.sin(dec_r) yp = dc_z * np.sin(ra_r) * np.sin(dec_r) zp = dc_z * np.cos(dec_r) return np.array([xp, yp, zp])
def __init__(self, M_matrix, npix_row, npix_col, delta_phi, delta_theta, freq, nbins, norm, linear_bin): self.Npix = M_matrix.shape[1] self.npix_row = npix_row self.npix_col = npix_col self.nbins = nbins self.norm = norm self.linear = linear_bin z = (1420 / freq) - 1 ##freqs must be in MHz self.delta_phi = cosmo.comoving_distance(z).value * delta_phi self.delta_theta = cosmo.comoving_distance(z).value * delta_theta self.L_x = self.delta_phi * self.npix_col self.L_y = self.delta_theta * self.npix_row self.M_matrix = np.real(M_matrix)
def lens_astropy(): import pylab as pl from astropy.cosmology import WMAP9 zl = np.linspace(0.01, 1.9, 100) zs = 2. wa = [] wc = [] angs = WMAP9.angular_diameter_distance(zs).value chis = WMAP9.comoving_distance(zs).value for zi in zl: angl = WMAP9.angular_diameter_distance(zi).value angls = WMAP9.angular_diameter_distance_z1z2(zi,zs).value chil = WMAP9.comoving_distance(zi).value chils = WMAP9.comoving_distance(zs).value-WMAP9.comoving_distance(zi).value wa.append(angl * angls / angs) wc.append(chil * chils / chis / (1+zi)) pl.plot(zl, wa) pl.plot(zl, wc, ls='--') pl.show()
def lens_astropy(): import pylab as pl from astropy.cosmology import WMAP9 zl = np.linspace(0.01, 1.9, 100) zs = 2. wa = [] wc = [] angs = WMAP9.angular_diameter_distance(zs).value chis = WMAP9.comoving_distance(zs).value for zi in zl: angl = WMAP9.angular_diameter_distance(zi).value angls = WMAP9.angular_diameter_distance_z1z2(zi, zs).value chil = WMAP9.comoving_distance(zi).value chils = WMAP9.comoving_distance(zs).value - WMAP9.comoving_distance( zi).value wa.append(angl * angls / angs) wc.append(chil * chils / chis / (1 + zi)) pl.plot(zl, wa) pl.plot(zl, wc, ls='--') pl.show()
def cube2hpx(simfile, hpxfile, freq, nside=4096, sim_res=7.8125, sim_size=(128, 128, 128), healpix_coord_files=None): """ Parameters ---------- simfile: string Name of a temperature simulation cube. hpxfile: string Name of an output healpix image. freq: float Frequency of interest in MHz. nside: integer NSIDE of the output HEALPix image. Must be a valid NSIDE for HEALPix. """ # Read in and interpolate simulation cubes to the redshift of interest. cube = np.load(simfile) # Determine the radial comoving distance r to the comoving shell at the # frequency of interest. f21 = 1420.40575177 # MHz z21 = f21 / freq - 1 dc = WMAP9.comoving_distance(z21).value # Get the vector coordinates (vx, vy, vz) of the HEALPIX pixels. if not healpix_coord_files: healpix_coord_files = 'healpix_coord_N{:d}.npy'.format(nside) if os.path.isfile(healpix_coord_files): vx, vy, vz = np.load(healpix_coord_files) else: vx, vy, vz = hp.pix2vec(nside, np.arange(hp.nside2npix(nside))) # Translate vector coordinates to comoving coordinates and determine the # corresponding cube indexes (xi, yi, zi). For faster operation, we will # use the mod function to determine the nearest neighboring pixels and # just grab the data points from those pixels instead of doing linear # interpolation. xi = np.mod(np.around(vx * dc / sim_res).astype(int), sim_size[0]) yi = np.mod(np.around(vy * dc / sim_res).astype(int), sim_size[1]) zi = np.mod(np.around(vz * dc / sim_res).astype(int), sim_size[2]) out = np.array(cube[xi, yi, zi]) hp.write_map(hpxfile, out, fits_IDL=False, dtype=np.float64, coord='C')
def getDistance(self): """ This method returns the distance of the object. :Param: Nothing. :Returns: Float with the distance of the object in lightyears units. :rtype: Float """ if (self.getRedShift() != ""): r = float(self.getRedShift()) d2 = Distance(cosmo.comoving_distance(r), u.lightyear) value = float(str(d2).split()[0]) divided = value / 1000000 #1 million if divided > 1: return "{:.2f} M".format(divided) else: return "{:.2f} ".format(value) else: return ""
def blind_distances(final): ''' Given an LSS catalog instance with Z filled, return the same instance with (blinded) cosmo distances. Parameters ---------- final: :class:`astropy.table.Table` LSS catalog Table. Returns ------- lsscatalog: :class:`astropy.table.Table` LSS catalog Table. ''' from astropy.cosmology import WMAP9 as cosmo isin = final['Z'] > 0. final['COSMO_BLINDCHI'][isin] = (cosmo.H(0) / 100.) * cosmo.comoving_distance(final['Z'][isin]) return final
def test_orthoslant_project(): Nside = 256 Npix = 12 * Nside**2 Omega = 4 * np.pi / float(Npix) Nfreq = 100 freqs = np.linspace(167.0, 177.0, Nfreq) dnu = np.diff(freqs)[0] Z = 1420 / freqs - 1. sig = 2.0 mu = 0.0 shell = np.random.normal(mu, sig, (Npix, Nfreq)) center = [np.sqrt(2) / 2., np.sqrt(2) / 2., 0] ## For orientation tests, replace with a single point at center # import healpy # cind = healpy.vec2pix(Nside, *center) # shell *= 0.0 # shell[cind] += 10 orthogrid = pspec_funcs.orthoslant_project(shell, center, 10, degrees=True) Nx, Ny, Nz = orthogrid.shape Lx = comoving_transverse_length(Z[Nfreq / 2], Omega) * Nx Ly = Lx Lz = comoving_radial_length(Z[Nfreq / 2], dnu) * Nz dV = comoving_voxel_volume(Z[Nfreq / 2], dnu, Omega) r_mpc = WMAP9.comoving_distance(Z).to("Mpc").value kbins, pk = pspec_funcs.box_dft_pspec(orthogrid, [Lx, Ly, Lz], r_mpc=r_mpc, cosmo=True) tol = np.sqrt(np.var(pk)) nt.assert_true(np.allclose(np.mean(pk), sig**2 * dV, atol=tol))
def CreateGalaxies(self, gals, id=0): """ Generate galaxies list. Output list will have these columns: # ID # RA # DEC # Redshift # Model # Age # Profile # Half-flux_radius # Axial_ratio # Position_angle # Johnson,V absolute # Johnson,V apparent Parameters ---------- self: obj Class instance. gals: dictionary Information about the galaxies. Includes: n_gals: int Number of galaxies z_low,z_high: float Minimum and maximum redshifts (converted to distances?). rad_low,rad_high: float Minimum and maximum galactic half-light radii (in arcseconds) sb_v_low, sb_v_high: float Minimum and maximum V-band average surface brightness within rad distribution: string Stellar distribution in the sky (e.g. power law, inverse power law, uniform, etc.) clustered: bool Cluster higher masses to centre? radius: float Radius in (units) radius_units: string Units of radius (above) offset_ra,offset_dec: float Offset of cluster from scene centre in mas Returns ------- outList: string The catalogue file produced """ bc95_models = np.array(('a', 'b', 'c', 'd', 'e', 'f')) bc95_ages = np.array(("10E5", "25E5", "50E5", "76E5", "10E6", "25E6", "50E6", "10E7", "50E7", "10E8", "50E8", "10E9")) out_file = "{}_gals_{:03d}.{}".format(self.prefix, id, self.cat_type) outList = os.path.join(self.out_path, out_file) if os.path.isfile(outList): os.remove(outList) # No append data_table = StipsDataTable.dataTableFromFile(outList) # Write star list (overwrite) self.logger.info("Creating catalogue %s", outList) # Generate galaxy list n_gals = int(gals['n_gals']) z_l = float(gals['z_low']) z_h = float(gals['z_high']) r_l = float(gals['rad_low']) r_h = float(gals['rad_high']) m_l = float(gals['sb_v_low']) m_h = float(gals['sb_v_high']) distribution = gals['distribution'] clustered = gals['clustered'] radius = float(gals['radius']) rad_units = gals['radius_units'] offset_ra = float( gals['offset_ra'] ) / 3600. #offset in RA arcseconds, convert to degrees. offset_dec = float( gals['offset_dec'] ) / 3600. #offset in DEC arcseconds, convert to degrees. self._log("info", "Wrote preamble") self._log("info", "Parameters are: {}".format(gals)) ids = np.arange(n_gals) # Roughly 50% spiral, 50% elliptical ellipRatio = 0.5 # binoDist = np.random.RandomState(seed=self.seed).binomial(1, ellipRatio, n_gals) binoDist = np.random.binomial(1, ellipRatio, n_gals) idx_ellip = np.where(binoDist == 1) idx_spiral = np.where(binoDist != 1) types = np.array(['expdisk'] * n_gals) types[idx_ellip] = 'devauc' n_ellip = len(idx_ellip[0]) n_spiral = n_gals - n_ellip # Axial ratio # Spiral = 0.1 to 1 # Elliptical = 0.5 to 1 axialRatioSpiralMin, axialRatioSpiralMax = 0.1, 1.0 axialRatioEllipMin, axialRatioEllipMax = 0.5, 1.0 axials = np.zeros(n_gals) # axials[idx_spiral] = np.random.RandomState(seed=self.seed).uniform(axialRatioSpiralMin, axialRatioSpiralMax, n_spiral) # axials[idx_ellip] = np.random.RandomState(seed=self.seed).uniform(axialRatioEllipMin, axialRatioEllipMax, n_ellip) axials[idx_spiral] = np.random.uniform(axialRatioSpiralMin, axialRatioSpiralMax, n_spiral) axials[idx_ellip] = np.random.uniform(axialRatioEllipMin, axialRatioEllipMax, n_ellip) # Position angle posAngleAlgo = 'uniform' # angles = np.random.RandomState(seed=self.seed).uniform(0.0, 359.9, n_gals) angles = np.random.uniform(0.0, 359.9, n_gals) # Half-flux radius - uniform # rads = np.random.RandomState(seed=self.seed).uniform(r_l, r_h, n_gals) rads = np.random.uniform(r_l, r_h, n_gals) # Redshifts # If both z_low and z_high are zero, do local galaxies. Distance is 0.5 Mpc -- 50 Mpc. # In the future, offer an option for straight distance or redshift. if z_l == 0. and z_h == 0.: z_label = "distance" # distances = np.random.RandomState(seed=self.seed).uniform(5.e5, 5.e7, n_gals) distances = np.random.uniform(5.e5, 5.e7, n_gals) zs = distances / 1.e3 convs = np.log10(distances) else: z_label = "redshift" # zs = np.random.RandomState(seed=self.seed).uniform(z_l, z_h, n_gals) zs = np.random.uniform(z_l, z_h, n_gals) distances = np.array(cosmo.comoving_distance(zs).to(u.pc)) convs = np.log10(np.array(cosmo.luminosity_distance(zs).to(u.pc))) # Luminosity function - power law lumPow = -1.8 # vmags = np.random.RandomState(seed=self.seed).power(np.abs(lumPow)+1.0, size=n_gals) vmags = np.random.power(np.abs(lumPow) + 1.0, size=n_gals) if lumPow < 0: vmags = 1.0 - vmags vmags = RescaleArray(vmags, m_l, m_h) vmags_abs = vmags - 5 * (convs - 1.) # models = np.random.RandomState(seed=self.seed).choice(bc95_models,size=n_gals) # ages = np.random.RandomState(seed=self.seed).choice(bc95_ages,size=n_gals) models = np.random.choice(bc95_models, size=n_gals) ages = np.random.choice(bc95_ages, size=n_gals) self._log("info", "Making Co-ordinates") x, y = self._MakeCoords(n_gals, radius, func=distribution, scale=2.8) x = RadiiUnknown2Arcsec(x, rad_units, distances) y = RadiiUnknown2Arcsec(y, rad_units, distances) if clustered: self._log("info", "Clustering") x, y = self._CenterObjByMass(x, y, 1 / vmags) self._log("info", "Converting Co-ordinates into RA,DEC") ras = x / 3600. #decimal degrees decs = y / 3600. #decimal degrees base_ra, base_dec = OffsetPosition(self.ra, self.dec, offset_ra, offset_dec) decs += base_dec idxg = np.where(decs > 90.) idxl = np.where(decs < -90.) decs[idxg] = 180. - decs[idxg] ras[idxg] = 180. + ras[idxg] decs[idxl] = -180. - decs[idxl] ras[idxl] = 180. + ras[idxl] ras = (ras + base_ra) % 360 metadata = { 'type': 'bc95', 'id': id, 'n_gals': n_gals, 'z_l': z_l, 'z_h': z_h, 'radius_l': r_l, 'radius_h': r_h, 'sb_v_l': m_l, 'sb_v_h': m_h, 'distribution': distribution, 'clustered': clustered, 'radius': radius, 'radius_units': rad_units, 'offset_ra': offset_ra, 'offset_dec': offset_dec, 'name': 'Galaxy Population Table', 'bandpass': '******' } data_table.meta = metadata t = Table() t['id'] = Column(data=ids) t['ra'] = Column(data=ras, unit=u.deg) t['dec'] = Column(data=decs, unit=u.deg) t[z_label] = Column(data=zs) t['model'] = Column(data=models) t['age'] = Column(data=ages, unit=u.yr) t['profile'] = Column(data=types) t['radius'] = Column(data=rads) t['axial_ratio'] = Column(data=axials, unit=u.deg) t['pa'] = Column(data=angles, unit=u.deg) t['absolute_surface_brightness'] = Column(data=vmags_abs, unit=u.mag) t['apparent_surface_brightness'] = Column(data=vmags, unit=u.mag) data_table.write_chunk(t) self._log("info", "Done creating catalogue") return outList
from astropy.table import Table import matplotlib.pyplot as plt from astropy.cosmology import WMAP9 import numpy as np cat = Table.read('CUT2_CLAUDS_HSC_VISTA_Ks23.3_PHYSPARAM_TM.fits') cat_gal = cat[cat['CLASS'] == 0] cat_massive_gal = cat_gal[cat_gal['MASS_BEST'] > 11.0] for z in np.arange(0.3, 2.5, 0.1): print('============='+str(z)+'================') dis = WMAP9.angular_diameter_distance(z).value # angular diameter distance at redshift z dis_l = WMAP9.comoving_distance(z - 0.1).value # comoving distance at redshift z-0.1 dis_h = WMAP9.comoving_distance(z + 0.1).value # comoving distance at redshift z+0.1 total_v = 4. / 3 * np.pi * (dis_h ** 3 - dis_l ** 3) # Mpc^3 survey_v = total_v * (4 / 41253.05) # Mpc^3 density = 0.00003 # desired constant (cumulative) volume number density (Mpc^-3) num = int(density * survey_v) cat_massive_z_slice = cat_massive_gal[abs(cat_massive_gal['ZPHOT'] - z) < 0.1] # massive galaxies in this z slice cat_massive_z_slice.sort('MASS_BEST') cat_massive_z_slice.reverse() cat_massive_z_slice = cat_massive_z_slice[:num] print(num) cat_sf = cat_massive_z_slice[cat_massive_z_slice['SSFR_BEST'] > -11] cat_qs = cat_massive_z_slice[cat_massive_z_slice['SSFR_BEST'] < -11] fig = plt.figure(figsize=(9, 9)) plt.rc('font', family='serif'), plt.rc('xtick', labelsize=15), plt.rc('ytick', labelsize=15) ax = fig.add_subplot(111)
distance = looktime * (ac.c / cosmo.H0).to(units) if (integration_type == "comoving"): pass elif (integration_type == "luminosity"): distance *= 1 + z else: raise (NotImplementedError('This integration type does not exist')) return distance.value zs = np.logspace(-4, 4., num=100) # zs = np.linspace(0, 30) comoving_dist = distance(zs, "comoving") luminosity_dist = distance(zs, "luminosity") # for i, (z, cd, ld) in enumerate(zip(zs, comoving_dist, luminosity_dist)): # print(f"z = {z:.1f}, D_C = {cd:.2f} Gpc, D_L = {ld:.2f} Gpc") plt.loglog(zs, comoving_dist, label="Comoving distance") plt.loglog(zs, luminosity_dist, label="Luminosity distance") plt.loglog(zs, (cosmo.comoving_distance(zs)).to('Gpc'), label='Astropy CD') plt.loglog(zs, (cosmo.luminosity_distance(zs)).to('Gpc'), label='Astropy LD') plt.ylabel("Distance (\SI{}{Gpc})") plt.xlabel("redshift $z$") plt.legend() plt.show()
def make_a_mock(iseed_potIGM): ################################################################## ## input parameters ################################################################## #np.random.seed(iseed_qso) # random seed (set later now) iseed_qso = 12 #random seed for quasar positions - same for all realizations # input is iseed_potIGM, which is random seed for lya spectra and for lensing potential field np.random.seed( iseed_potIGM ) # set for now - will get changed for qso pos and then back ang_size = 0.5 * np.pi / 180. # angular size of field in radians ! includes a buffer zone of 10% on all sides Ngrid = 16 # 1d number of pixels in simulated field Nqso = 400 # number of backlights sqrtNqso = Nqso**0.5 Nfrequ = 20 # number of pixels in each spectra dz = 0.02 # redshift zs1 = 2.0 # lowest redshift of forest Nl = 21 # number of l-modes to a side Rmin = 0.1 # minimum correlation length, flatten correlation function PlotJump = 3 DFTorder = True # order modes in standard DFT order fullF = False # do only the diagonal values for Fisher matrix or the whole thing factor = 10.0 # factor by which the potential power is boosted for testing Ndsets = 1 # number of simulated data sets pix_noise_factor = 1.1 # pixels are given uncorrelated noise that # is pix_noise_factor x the max of the correlation # function, C(Rmin), must be > 1 ################################################################## # -------------------- Create output directories ----------------------------------------------------------- try: os.makedirs('Data_nqso' + str(Nqso) + '_npix' + str(Nfrequ) + '_boost' + str(factor) + '_ngrid' + str(Ngrid) + '/') except OSError as e: if e.errno != errno.EEXIST: raise try: os.makedirs('XY_nqso' + str(Nqso) + '_npix' + str(Nfrequ) + '_boost' + str(factor) + '_ngrid' + str(Ngrid) + '/') except OSError as e: if e.errno != errno.EEXIST: raise DataDir = 'Data_nqso' + str(Nqso) + '_npix' + str(Nfrequ) + '_boost' + str( factor) + '_ngrid' + str(Ngrid) + '/' PositionDir = 'XY_nqso' + str(Nqso) + '_npix' + str( Nfrequ) + '_boost' + str(factor) + '_ngrid' + str(Ngrid) + '/' print("Here is the seed:", iseed_potIGM) ################################################################## # some derived quantities ################################################################## zs2 = zs1 + dz * Nfrequ # highest redshift of forest Dss = cosmo.comoving_distance([zs1, zs2]) Ds = Dss[1].value zlength = Dss[1].value - Dss[0].value ds_vec = np.arange(Dss[0].value, Dss[1].value, (Dss[1].value - Dss[0].value) / Nfrequ) ################################################################## # make the correlation function and its derivative ################################################################## corrfunc, dcorrfunc = sp.make_correlation_functions(Rmin) ################################################################## # Deflection field ################################################################## phi_field, df_power_phi = sp.make_potential_field(Ngrid, ang_size, factor=factor) Xqso, Yqso, X_source, Y_source = sp.make_deflections( phi_field, ang_size, Ngrid, Nqso, iseed_qso, iseed_potIGM) np.savetxt(PositionDir + 'Xqso_' + str(iseed_potIGM).zfill(6) + '.txt', Xqso) np.savetxt(PositionDir + 'Yqso_' + str(iseed_potIGM).zfill(6) + '.txt', Yqso) np.savetxt(PositionDir + 'Xsource_' + str(iseed_potIGM).zfill(6) + '.txt', X_source) np.savetxt(PositionDir + 'Ysource_' + str(iseed_potIGM).zfill(6) + '.txt', Y_source) Nqso = len(Xqso) Cmax = corrfunc(Rmin) ################################################################## ### make simulated spectra ################################################################## print("creating fake spectra ...") start_time = time.time() for i in range(Ndsets): print((" " + repr(i + 1) + " out of " + repr(Ndsets))) spectra, cube_im = sp.make_spectra(Xqso, Yqso, X_source, Y_source, Ngrid, Nqso, Nfrequ, zlength, ang_size, ds_vec, np.sqrt(pix_noise_factor * Cmax)) print(("--- %s seconds ---" % (time.time() - start_time))) mock = [ Ngrid, Nqso, Nfrequ, ang_size, iseed_potIGM, phi_field, Xqso, Yqso, spectra ] import pickle filenamemaybe = DataDir + 'mock.' + str(iseed_potIGM).zfill(6) print(filenamemaybe) with open(filenamemaybe, 'wb') as fp: pickle.dump(mock, fp) return
def lightcone(**kwargs ): #set defaults: mode = 'xH' marker = 'xH_' N = 500 DIM = 200 Box_length = 300 z_start = 6 z_end = 10 nboxes = 21 directory = '/Users/michael/Documents/MSI-C/21cmFAST/Boxes/z6-10/OriginalTemperatureBoxesNoGaussianities/' halo_location_x = 0 halo_location_y = 0 #sort arguments if 'marker' in kwargs: marker = kwargs.get('marker') if 'DIM' in kwargs: DIM = kwargs.get('DIM') if 'Box_length' in kwargs: Box_length = kwargs.get('Box_length') if 'z_start' in kwargs: z_start = kwargs.get('z_start') if 'z_end' in kwargs: z_end = kwargs.get('z_end') if 'nboxes' in kwargs: nboxes = kwargs.get('nboxes') if 'N' in kwargs: N = kwargs.get('N') else: N = 50*nboxes if 'directory' in kwargs: directory = kwargs.get('directory') if 'halo_location_x' in kwargs: halo_location_x = kwargs.get('halo_location_x') if 'halo_location_y' in kwargs: halo_location_y = kwargs.get('halo_location_y') if 'return_redshifts' in kwargs: return_redshifts = kwargs.get('return_redshifts') else: return_redshifts = False if 'sharp_cutoff' in kwargs: sharp_cutoff = kwargs.get('sharp_cutoff') else: sharp_cutoff = np.inf #21cmFAST boxes have different naming tags, if it is an ionization box the redshifts info will be found #at different parts of the filename as compared to a density box if 'smoothed' in marker: #this is a density box box s,e=25,31 else: if 'xH' in marker: s,e = 10, 20 else: print('We can not identify what box this is') return -1 z_range_of_boxes = np.linspace(z_start,z_end,nboxes) #print(z_end) # print(z_start) # print(nboxes) # print(z_range_of_boxes) #################################################### # useful functions #################################################### def box_maker(name): #reads in the boxes data = np.fromfile(directory + name ,dtype=np.float32) box = data.reshape((DIM,DIM,DIM)) return box box_path = np.zeros((len(z_range_of_boxes)), dtype = 'object') box_path_redshifts = np.zeros((len(box_path))) for fn in os.listdir(directory): #parse the boxes #print(fn) for z in range(len(z_range_of_boxes)): if marker in fn and str(np.round(z_range_of_boxes[z],2)) in fn[s:e]: box_path[z] = fn #index = box_path[z].find('_z0') #start = index + len('_z0') #box_path_redshifts[z] = float(box_path[z][start:start + 4]) #function to determine weighting of each redshift to boxes def find_sandwiched_bins(z_range, z): z_floor = np.min(z_range) z_ceil = z_range[1] binn = 1 while(z_ceil <= np.max(z_range)): if ((z >= z_floor) and (z < z_ceil)): return (z_floor, z_ceil) z_floor = z_ceil if z_ceil == np.max(z_range): break z_ceil = z_range[binn+1] binn += 1 #safety net if binn > 1000: break def comoving2pixel(DIM, Box_length, comoving_distance): return int(float(comoving_distance * DIM)/float(Box_length)) def didweswitchbox(historyofzminus, z_minus, ctr): if z_minus > historyofzminus[ctr - 1 ]: return True #################################################### # initialize all relevant arrays #################################################### lightcone = np.zeros((N, DIM, DIM)) lightcone_halo = np.zeros((N)) z_range = np.linspace(z_start,z_end,N) z = z_range[0] ctr = 0 comoving_distance_z0_zstart = cosmo.comoving_distance(z_range[0]).value prev_pix_loc = 0 pixel_addition = 0 pixel_origin = 0 pixel_location_relative_to_origin = 0 historyofzminus = [] zs = [] #################################################### # loop through redshifts #################################################### box_path_redshifts = z_range_of_boxes while(z < np.max(z_range)): z_sandwhich = find_sandwiched_bins(box_path_redshifts, z) z_minus = z_sandwhich[0] historyofzminus.append(z_minus) z_plus = z_sandwhich[1] xH_minus = box_maker(box_path[list(box_path_redshifts).index(z_minus)]) xH_plus = box_maker(box_path[list(box_path_redshifts).index(z_plus)]) comoving_distance_z = cosmo.comoving_distance(z).value comoving_distance_z0_to_z = comoving_distance_z - comoving_distance_z0_zstart comoving_distance_from_last_switch = cosmo.comoving_distance(z_minus).value if ctr == 0: pixel_addition = comoving2pixel(DIM,Box_length, comoving_distance_z-comoving_distance_z0_zstart) prev_pix_loc = pixel_addition pixel_origin = 0 #save this redshift zs.append(z) lightcone[ctr,:,:] = (xH_plus[:,:,pixel_addition] - xH_minus[:,:,pixel_addition])*((z - z_minus)/(z_plus - z_minus)) + xH_minus[:,:,pixel_addition] #increment counter and redshift ctr += 1 z = z_range[ctr] #skip to the next step continue else: if didweswitchbox(historyofzminus, z_minus, ctr): pixel_origin = prev_pix_loc pixel_location_relative_to_origin = comoving2pixel(DIM,Box_length, comoving_distance_z-comoving_distance_from_last_switch) pixel_addition = (pixel_location_relative_to_origin + pixel_origin)%DIM prev_pix_loc = pixel_addition lightcone[ctr,:,:] = (xH_plus[:,:,pixel_addition] - xH_minus[:,:,pixel_addition])*((z - z_minus)/(z_plus - z_minus)) + xH_minus[:,:,pixel_addition] #lightcone_halo[ctr] = (xH_plus[halo_location_x][halo_location_y][pixel_addition] - xH_minus[halo_location_x][halo_location_y][pixel_addition])*((z - z_minus)/(z_plus - z_minus)) + xH_minus[halo_location_x][halo_location_y][pixel_addition] #save this redshift zs.append(z) #does the user want us to stop the z scroll after a particular value? if ctr >= sharp_cutoff: if return_redshifts: return lightcone[1:sharp_cutoff,:,] , np.array(zs[1:]) else: return lightcone[1:sharp_cutoff,:,] ctr += 1 z = z_range[ctr] #pl.savefig(str(ctr)+'.png') #safety net if ctr > N: break #return the lightcone history as an array across all redshifts #return the lightcone history as the redshift log (should the user specify that) if return_redshifts: return lightcone , np.array(zs) else: return lightcone
# Planck13.comoving_distance(ar_z)) # # plt.plot(ar_z, Planck13.comoving_distance(ar_z) / Planck13.comoving_distance(ar_z)) # plt.plot(ar_z, Planck13.comoving_distance(ar_z + ar_delta_z_planck13 - ar_delta_z_wmap7) / # Planck13.comoving_distance(ar_z)) # plt.show() # print(scipy.misc.derivative(func=Planck13.comoving_distance, x0=2, dx=0.1)) # ar_dcmv_dz_planck13 = np.array([scipy.misc.derivative( # func=lambda x: Planck13.comoving_distance(x).value, x0=z, dx=0.01) for z in ar_z]) # ar_dcmv_dz_wmap7 = np.array([scipy.misc.derivative( # func=lambda x: WMAP7.comoving_distance(x).value, x0=z, dx=0.01) for z in ar_z]) # plt.plot(ar_z, -(ar_dcmv_dz_planck13 - ar_dcmv_dz_wmap7) * ar_delta_z_planck13) # plt.show() del scipy.misc ar_base_cmvd_planck13 = Planck13.comoving_distance(ar_z) ar_true_planck13_cmvd = Planck13.comoving_distance(ar_z + ar_delta_z_planck13) ar_base_cmvd_wmap5 = WMAP5.comoving_distance(ar_z) ar_wmap5_apparent_cmvd = WMAP5.comoving_distance(ar_z + ar_delta_z_planck13) ar_base_cmvd_wmap7 = WMAP7.comoving_distance(ar_z) ar_wmap7_apparent_cmvd = WMAP7.comoving_distance(ar_z + ar_delta_z_planck13) ar_base_cmvd_wmap9 = WMAP9.comoving_distance(ar_z) ar_wmap9_apparent_cmvd = WMAP9.comoving_distance(ar_z + ar_delta_z_planck13) plt.plot(ar_z, ar_true_planck13_cmvd - ar_base_cmvd_planck13) plt.plot(ar_z, ar_wmap5_apparent_cmvd - ar_base_cmvd_wmap5) plt.plot(ar_z, ar_wmap7_apparent_cmvd - ar_base_cmvd_wmap7) plt.plot(ar_z, ar_wmap9_apparent_cmvd - ar_base_cmvd_wmap9) # plt.plot(ar_z, ar_wmap7_apparent_cmvd - ar_true_planck13_cmvd) plt.show()
def extinction(spec, red, coord): """ :param spec: (numpy array) XSpectrum1D objects: use clamato_read.py :param red: (numpy array) redshift values :param coord: (numpy array) coordinates :return: unred_spec: (numpy array) de-reddened spec """ import numpy as np from numpy.lib.polynomial import poly1d import astropy.units as u from astropy.coordinates import SkyCoord from dustmaps.bayestar import BayestarQuery from astropy.cosmology import WMAP9 as cosmo from linetools.spectra.xspectrum1d import XSpectrum1D r = range(len(spec)) Mpc = cosmo.comoving_distance(red) bayestar = BayestarQuery() coords = [ SkyCoord(coord[i][0] * u.deg, coord[i][1] * u.deg, distance=Mpc[i], frame='fk5') for i in r ] ebv = [bayestar(i) for i in coords] #to get the ebv values for each galaxy unred_spec = [] for i in r: x = 10000. / np.array(spec[i].wavelength) # Convert to inverse microns npts = x.size a = np.zeros(npts, dtype=np.float) b = np.zeros(npts, dtype=np.float) r_v = 3.1 good = np.where((x >= 0.3) & (x < 1.1)) if len(good[0]) > 0: a[good] = 0.574 * x[good]**(1.61) b[good] = -0.527 * x[good]**(1.61) good = np.where((x >= 1.1) & (x < 3.3)) if len(good[0]) > 0: # Use new constants from O'Donnell (1994) y = x[good] - 1.82 c1 = np.array([ 1., 0.104, -0.609, 0.701, 1.137, -1.718, -0.827, 1.647, -0.505 ]) # from O'Donnell c2 = np.array([ 0., 1.952, 2.908, -3.989, -7.985, 11.102, 5.491, -10.805, 3.347 ]) a[good] = poly1d(c1[::-1])(y) b[good] = poly1d(c2[::-1])(y) good = np.where((x >= 3.3) & (x < 8)) if len(good[0]) > 0: y = x[good] a[good] = 1.752 - 0.316 * y - (0.104 / ((y - 4.67)**2 + 0.341)) # + f_a b[good] = -3.090 + 1.825 * y + (1.206 / ((y - 4.62)**2 + 0.263)) # + f_b good = np.where((x >= 8) & (x <= 11)) if len(good[0]) > 0: y = x[good] - 8. c1 = np.array([-1.073, -0.628, 0.137, -0.070]) c2 = np.array([13.670, 4.257, -0.420, 0.374]) a[good] = poly1d(c1[::-1])(y) b[good] = poly1d(c2[::-1])(y) # Now apply extinction correction to input flux vector a_v = r_v * ebv[i] a_lambda = a_v * (a + b / r_v) funred = spec[i].flux * 10.**(0.4 * a_lambda) # Derive unreddened flux funred = np.asarray(funred) unred_spec.append(XSpectrum1D(spec[i].wavelength, funred, spec[i].sig)) return np.asarray(unred_spec)
def z_to_dist(self, z): ''' Given a redshift, finds the correspoding comoving distance ''' return cosmo.comoving_distance(z)
def __init__(self, time_grid, gamma_grid, emission_region, injected_spectrum): ''' This is the constructor of our SSC process with * time_grid = dict(minimum, maximum time, binning) initializing the time grid * gamma_grid = dict(minimum, maximum Lorentz factor, binning) initializing the Lorentz factor grid * emission_region dict(radius, magnetic field, escaping time, Doppler-Factor) with parameters describing the emission region, escaping time in order of R/c * injected_spectrum dict(norm, index) initializing the injected spectrum (a powerlaw for now). ''' # emission regions attributes definitions self.R = emission_region['R'] # in cm self.volume = 4 / 3 * pi * self.R**3 self.crossing_time = self.R / c self.B = emission_region['B'] # in Gauss self.t_esc = emission_region['t_esc'] * self.crossing_time self.U_B = self.B**2 / (8. * pi) # magnetic field density self.gamma = emission_region['gamma'] self.beta = np.sqrt(1 - 1 / self.gamma**2) self.theta = emission_region['theta'] self.z = emission_region['z'] self.distance = cosmo.comoving_distance(self.z) # in Mpc # time grid attributes definition self.time_min = time_grid['time_min'] * self.crossing_time self.time_max = time_grid['time_max'] * self.crossing_time self.time_bins = time_grid['time_bins'] self.delta_t = (self.time_max - self.time_min) / self.time_bins self.time_grid = np.linspace(self.time_min, self.time_max, self.time_bins) # gamma grid attributes defintion self.gamma_min = gamma_grid['gamma_min'] self.gamma_max = gamma_grid['gamma_max'] self.gamma_bins = gamma_grid['gamma_bins'] # following Eq.(5) of the Reference, LorentzFactor grid has to be logspaced # we loop over range(-1,N+2) include \gamma_{-1} and \gamma{N+1} gamma_grid = [] self.gamma_min_calc = self.gamma_max**( 1 / self.gamma_bins) * self.gamma_min**( (self.gamma_bins - 1) / self.gamma_bins ) #(due to dividing by p=0 if gamma=1) for j in range(-1, self.gamma_bins + 2): gamma_grid.append(self.gamma_min_calc * (self.gamma_max / self.gamma_min_calc)**( (j - 1) / (self.gamma_bins - 1))) # gamma_grid_ext will be the grid that contains \gamma_{-1} and \gamma{N+1} self.gamma_grid_ext = np.array(gamma_grid) # gamma_grid will be the grid with elements from \gamma_{0} to \gamma_{N} self.gamma_grid = self.gamma_grid_ext[1:-1] # energy grid for use in calculating the synchrotron emission self.energy_grid = self.gamma_grid * E_rest # let's create an array for the density of radiation self.U_rad = 0 # injected spectrum attributes # Distinction between the needed parameters depending on the injection type self.inj_spectr_type = injected_spectrum['type'] if self.inj_spectr_type == 'constant': self.inj_spectr_norm = injected_spectrum['norm'] elif self.inj_spectr_type == 'power-law': self.inj_spectr_norm = injected_spectrum['norm'] self.inj_spectr_index = injected_spectrum['alpha'] elif self.inj_spectr_type == 'broken power-law': self.inj_spectr_norm = injected_spectrum['norm'] self.inj_spectr_index_1 = injected_spectrum['alpha1'] self.inj_spectr_index_2 = injected_spectrum['alpha2'] self.e_break = injected_spectrum['e_break'] elif self.inj_spectr_type == 'gaussian': self.inj_spectr_norm = injected_spectrum['norm'] self.inj_spectr_mu = injected_spectrum['mu'] self.inj_spectr_sig = injected_spectrum['sig'] self.inj_time = injected_spectrum[ 't_inj'] * self.crossing_time # injection time
def comov_dist(z): return WMAP9.comoving_distance(z).to("Mpc").value
def lightcone(**kwargs): #set defaults: mode = 'xH' marker = 'xH_' N = 500 DIM = 200 Box_length = 300 z_start = 10 z_end = 6 nboxes = 21 directory = '/Users/michael/Documents/MSI-C/21cmFAST/Boxes/z6-10/OriginalTemperatureBoxesNoGaussianities/' halo_location_x = 0 halo_location_y = 0 slice = DIM - 1 #sort arguments if 'marker' in kwargs: marker = kwargs.get('marker') if 'DIM' in kwargs: DIM = kwargs.get('DIM') if 'N' in kwargs: N = kwargs.get('N') if 'Box_length' in kwargs: Box_length = kwargs.get('Box_length') if 'z_start' in kwargs: z_start = kwargs.get('z_start') if 'z_end' in kwargs: z_end = kwargs.get('z_end') if 'nboxes' in kwargs: nboxes = kwargs.get('nboxes') if 'directory' in kwargs: directory = kwargs.get('directory') if 'halo_location_x' in kwargs: halo_location_x = kwargs.get('halo_location_x') if 'halo_location_y' in kwargs: halo_location_y = kwargs.get('halo_location_y') if 'box_slice' in kwargs: slice = kwargs.get('box_slice') if 'return_redshifts' in kwargs: return_redshifts = kwargs.get('return_redshifts') else: return_redshifts = False if 'sharp_cutoff' in kwargs: sharp_cutoff = kwargs.get('sharp_cutoff') else: sharp_cutoff = np.inf z_range_of_boxes = np.linspace(z_start, z_end, nboxes) #print(z_end) # print(z_start) # print(nboxes) #print(z_range_of_boxes) #################################################### # useful functions #################################################### def box_maker(name): #reads in the boxes data = np.fromfile(directory + name, dtype=np.float32) box = data.reshape((DIM, DIM, DIM)) return box box_path = np.zeros((len(z_range_of_boxes)), dtype='object') box_path_redshifts = np.zeros((len(box_path))) for fn in os.listdir(directory): #parse the boxes #print(fn) for z in range(len(z_range_of_boxes)): #print(z_range_of_boxes[z]) if marker in fn and str(np.round(z_range_of_boxes[z], 2)) in fn: #print(z_range_of_boxes[z], fn) box_path[z] = fn index = box_path[z].find('_z0') start = index + len('_z0') box_path_redshifts[z] = float(box_path[z][start:start + 4]) #print(box_path_redshifts) # print(box_path) #function to determine weighting of each redshift to boxes def find_sandwiched_bins(z_range, z): z_floor = np.max(z_range) z_ceil = z_range[1] binn = 1 while (z_ceil >= np.min(z_range)): if ((z <= z_floor) and (z > z_ceil)): return (z_ceil, z_floor) z_floor = z_ceil if z_ceil == np.max(z_range): break z_ceil = z_range[binn + 1] binn += 1 #safety net if binn > 1000: print('breaking') break def comoving2pixel(DIM, Box_length, comoving_distance): return int(float(comoving_distance * DIM) / float(Box_length)) def didweswitchbox(historyofzminus, z_plus, ctr): if z_plus < historyofzminus[ctr - 1]: return True else: return False #################################################### # initialize all relevant arrays #################################################### lightcone = np.zeros((N, DIM, DIM)) lightcone_halo = np.zeros((N)) z_range = np.linspace(z_start, z_end, N) zs = [] z = z_range[0] ctr = 0 comoving_distance_z0_zstart = cosmo.comoving_distance(z_range[0]).value prev_pix_loc = 0 pixel_addition = 0 pixel_origin = 0 pixel_location_relative_to_origin = 0 historyofzminus = [] #################################################### # loop through redshifts #################################################### while (z > np.min(z_range)): z_sandwhich = find_sandwiched_bins(box_path_redshifts, z) z_minus = z_sandwhich[0] z_plus = z_sandwhich[1] historyofzminus.append(z_plus) xH_minus = box_maker(box_path[list(box_path_redshifts).index(z_minus)]) xH_plus = box_maker(box_path[list(box_path_redshifts).index(z_plus)]) comoving_distance_z = cosmo.comoving_distance(z).value comoving_distance_z0_to_z = comoving_distance_z0_zstart - comoving_distance_z comoving_distance_from_last_switch = cosmo.comoving_distance( z_plus).value if ctr == 0: pixel_addition = comoving2pixel(DIM, Box_length, comoving_distance_z0_to_z) prev_pix_loc = -pixel_addition + slice pixel_origin = slice else: if didweswitchbox(historyofzminus, z_plus, ctr): print('we switched box to', z_plus) #print(z_plus, z , historyofzminus[ctr-1]) pixel_origin = prev_pix_loc pixel_location_relative_to_origin = -comoving2pixel( DIM, Box_length, comoving_distance_from_last_switch - comoving_distance_z) pixel_addition = (pixel_location_relative_to_origin + pixel_origin) % DIM prev_pix_loc = pixel_addition zs.append(z) lightcone[ctr, :, :] = ( xH_plus[pixel_addition, :, :] - xH_minus[pixel_addition, :, :]) * ( (z - z_minus) / (z_plus - z_minus)) + xH_minus[pixel_addition, :, :] lightcone_halo[ctr] = ( xH_plus[pixel_addition][halo_location_x][halo_location_y] - xH_minus[pixel_addition][halo_location_x][halo_location_y]) * ( (z - z_minus) / (z_plus - z_minus) ) + xH_minus[pixel_addition][halo_location_x][halo_location_y] ctr += 1 z = z_range[ctr] #pl.savefig(str(ctr)+'.png') #safety net if ctr > N: break if ctr >= sharp_cutoff: if return_redshifts: return lightcone[1:sharp_cutoff, :, ], np.array(zs[1:]) else: return lightcone[1:sharp_cutoff, :, ] #return the lightcone history as an array across all redshifts if return_redshifts: return lightcone, np.array(zs) else: return lightcone
from scipy.special import spherical_jn as jl import numpy as np from astropy.cosmology import WMAP9 import matplotlib.pyplot as p import matplotlib.colors as mcolors import matplotlib.cm as cm freqs = np.linspace(167.075, 177.075, 129) Zs = 1420. / freqs - 1. r_mpc = WMAP9.comoving_distance(Zs).to("Mpc").value Nchan = freqs.size r_mpc = np.linspace(min(r_mpc), max(r_mpc), Nchan) dr = r_mpc[1] - r_mpc[0] kz = np.fft.fftfreq(Nchan, d=dr) * 2 * np.pi kz = kz[kz > 0] lmin = 0 lmax = 700 dl = 25 ki = 0 normalize = mcolors.Normalize(vmin=lmin, vmax=lmax) colormap = cm.viridis for l in range(lmin, lmax, dl): check = np.any((kz[ki] * r_mpc) > l) print l, check if check: p.plot(r_mpc, jl(l, kz[ki] * r_mpc)**2,
def lightcone(**kwargs ): #set defaults: mode = 'xH' marker = 'xH_' N = 500 DIM = 200 Box_length = 300 z_start = 10 z_end = 6 nboxes = 21 directory = '/Users/michael/Documents/MSI-C/21cmFAST/Boxes/z6-10/OriginalTemperatureBoxesNoGaussianities/' slice = DIM - 1 #sort arguments if 'marker' in kwargs: marker = kwargs.get('marker') if 'DIM' in kwargs: DIM = kwargs.get('DIM') if 'z_range_of_boxes' in kwargs: z_range_of_boxes = kwargs.get('z_range_of_boxes') nboxes = len(z_range_of_boxes) z_start = np.max(z_range_of_boxes) z_end = np.min(z_range_of_boxes) print(z_start,z_end, nboxes) if 'N' in kwargs: N = kwargs.get('N') else: N = 50*nboxes if 'Box_length' in kwargs: Box_length = kwargs.get('Box_length') if 'box_slice' in kwargs: slice = kwargs.get('box_slice') if 'return_redshifts' in kwargs: return_redshifts = kwargs.get('return_redshifts') else: return_redshifts = False if 'sharp_cutoff' in kwargs: sharp_cutoff = kwargs.get('sharp_cutoff') else: sharp_cutoff = np.inf if 'halo_boxes_z' in kwargs: halo_boxes_z = kwargs.get('halo_boxes_z') #21cmFAST boxes have different naming tags, if it is an ionization box the redshifts info will be found #at different parts of the filename as compared to a density box if 'smoothed' in marker: #this is a density box box s,e=25,31 else: if 'xH' in marker: s,e = 10, 20 else: if 'halos' in marker: s , e = 5, 10 else: print('We can not identify what box this is') return -1 #the total range of redshifts that this lightcone will span z_range_of_boxes = np.linspace(z_start,z_end,nboxes) #################################################### # useful functions #################################################### #this function determines which boxes a given redshift lies between def find_sandwiched_bins(z_range, z): z_floor = np.max(z_range) z_ceil = z_range[1] binn = 1 while(z_ceil >= np.min(z_range)): if ((z <= z_floor) and (z > z_ceil)): return ( z_ceil, z_floor) z_floor = z_ceil if z_ceil == np.max(z_range): print('looking for ' , z_range, z) break z_ceil = z_range[binn+1] binn += 1 #safety net if binn > 1000: print('breaking') break #function which converts a comoving distance to a pixel location within the box def comoving2pixel(DIM, Box_length, comoving_distance): return int(float(comoving_distance * DIM)/float(Box_length)) #function which determines whether we have exceeded the maximum allowable redshift for a box def didweswitchbox(historyofzminus, z_plus, ctr): if z_plus < historyofzminus[ctr - 1 ]: return True else: return False #################################################### # initialize all relevant arrays #################################################### lightcone = np.zeros((N, DIM, DIM)) lightcone_halo = np.zeros((N)) z_range = np.linspace(z_start,z_end,N) zs = [] z = z_range[0] ctr = 0 comoving_distance_z0_zstart = cosmo.comoving_distance(z_range[0]).value prev_pix_loc = 0 pixel_addition = 0 pixel_origin = 0 pixel_location_relative_to_origin = 0 historyofzminus = [] #################################################### # loop through redshifts #################################################### box_path_redshifts = z_range_of_boxes #scroll through all the redshifts and pick out the slice of the box that corresponds to that z while(z > np.min(z_range)): #this redshift is sandwiched between the following z z_sandwhich = find_sandwiched_bins(box_path_redshifts, z) z_minus = z_sandwhich[0] z_plus = z_sandwhich[1] historyofzminus.append(z_plus) #these are the boxes that z is sandwiched between xH_minus = halo_boxes_z[list(box_path_redshifts).index(z_minus)] xH_plus = halo_boxes_z[list(box_path_redshifts).index(z_plus)] #convert that redshift to a comoving distance comoving_distance_z = cosmo.comoving_distance(z).value comoving_distance_z0_to_z = comoving_distance_z0_zstart - comoving_distance_z comoving_distance_from_last_switch = cosmo.comoving_distance(z_plus).value if ctr == 0: pixel_addition = comoving2pixel(DIM,Box_length, comoving_distance_z0_to_z) prev_pix_loc = -pixel_addition + slice pixel_origin = slice #save this redshift zs.append(z) lightcone[ctr,:,:] = (xH_plus[:,:,slice] - xH_minus[:,:,slice])*((z - z_minus)/(z_plus - z_minus)) + xH_minus[:,:,slice] #increment counter and redshift ctr += 1 z = z_range[ctr] #skip to the next step continue else: if didweswitchbox(historyofzminus, z_plus, ctr): pixel_origin = prev_pix_loc pixel_location_relative_to_origin = -comoving2pixel(DIM,Box_length, comoving_distance_from_last_switch - comoving_distance_z) pixel_addition = (pixel_location_relative_to_origin + pixel_origin)%DIM prev_pix_loc = pixel_addition #save this redshift zs.append(z) #save the box information for this particular lightcone slice lightcone[ctr,:,:] = (xH_plus[pixel_addition,:,:] - xH_minus[pixel_addition,:,:])*((z - z_minus)/(z_plus - z_minus)) + xH_minus[pixel_addition,:,:] ctr += 1 z = z_range[ctr] #pl.savefig(str(ctr)+'.png') #safety net if ctr > N: break #does the user want us to stop the z scroll after a particular value? if ctr >= sharp_cutoff: if return_redshifts: return lightcone[0:sharp_cutoff,:,] , np.array(zs[0:]) else: return lightcone[0:sharp_cutoff,:,] #return the lightcone history as the redshift log (should the user specify that) if return_redshifts: return lightcone[0:int(N-1),:,] , np.array(zs) else: return lightcone[0:int(N-1),:,]