def test_pospix(self): # Posmap separable and non-separable on CAR for res in [6,12,24]: shape,wcs = enmap.fullsky_geometry(res=np.deg2rad(res/60.),proj='car') posmap1 = enmap.posmap(shape,wcs) posmap2 = enmap.posmap(shape,wcs,separable=True) assert np.all(np.isclose(posmap1,posmap2)) # Pixmap plain pres = 0.5 shape,wcs = enmap.geometry(pos=(0,0),shape=(30,30),res=pres*u.degree,proj='plain') yp,xp = enmap.pixshapemap(shape,wcs) assert np.all(np.isclose(yp,pres*u.degree)) assert np.all(np.isclose(xp,pres*u.degree)) yp,xp = enmap.pixshape(shape,wcs) parea = enmap.pixsize(shape,wcs) assert np.isclose(parea,(pres*u.degree)**2) assert np.isclose(yp,pres*u.degree) assert np.isclose(xp,pres*u.degree) pmap = enmap.pixsizemap(shape,wcs) assert np.all(np.isclose(pmap,(pres*u.degree)**2)) # Pixmap CAR pres = 0.1 dec_cut = 89.5 # pixsizemap is not accurate near the poles currently shape,wcs = enmap.band_geometry(dec_cut=dec_cut*u.degree,res=pres*u.degree,proj='car') # Current slow and general but inaccurate near the poles implementation pmap = enmap.pixsizemap(shape,wcs) # Fast CAR-specific pixsizemap implementation dra, ddec = wcs.wcs.cdelt*u.degree dec = enmap.posmap([shape[-2],1],wcs)[0,:,0] area = np.abs(dra*(np.sin(np.minimum(np.pi/2.,dec+ddec/2))-np.sin(np.maximum(-np.pi/2.,dec-ddec/2)))) Nx = shape[-1] pmap2 = enmap.ndmap(area[...,None].repeat(Nx,axis=-1),wcs) assert np.all(np.isclose(pmap,pmap2))
def wfactor(n, mask, sht=True, pmap=None, equal_area=False): """ Approximate correction to an n-point function for the loss of power due to the application of a mask. For an n-point function using SHTs, this is the ratio of area weighted by the nth power of the mask to the full sky area 4 pi. This simplifies to mean(mask**n) for equal area pixelizations like healpix. For SHTs on CAR, it is sum(mask**n * pixel_area_map) / 4pi. When using FFTs, it is the area weighted by the nth power normalized to the area of the map. This also simplifies to mean(mask**n) for equal area pixels. For CAR, it is sum(mask**n * pixel_area_map) / sum(pixel_area_map). If not, it does an expensive calculation of the map of pixel areas. If this has been pre-calculated, it can be provided as the pmap argument. """ assert mask.ndim == 1 or mask.ndim == 2 if pmap is None: if equal_area: npix = mask.size pmap = 4 * np.pi / npix if sht else enmap.area( mask.shape, mask.wcs) / npix else: pmap = enmap.pixsizemap(mask.shape, mask.wcs) return np.sum((mask**n) * pmap) / np.pi / 4. if sht else np.sum( (mask**n) * pmap) / np.sum(pmap)
def _get_jysr2thermo(self, mode="car"): assert (mode == "car") if self.jysr2thermo is None: pixsizemap = enmap.pixsizemap(self.shape, self.wcs) self.jysr2thermo = (1e-3 * jysr2thermo(148) / pixsizemap); del pixsizemap self.jysr2thermo = self.jysr2thermo.astype(np.float32) return self.jysr2thermo
def get_power(map_list, ivar_list, a, b, mask, N=20): """ Calculate the average coadded flattened power spectrum P_{ab} used to generate simulation for the splits. Inputs: map_list: list of source free splits ivar_list: list of the inverse variance maps splits a: 0,1,2 for I,Q,U respectively b:0,1,2 for I,Q,U, respectively N: window to smooth the power spectrum by in the rolling average. mask: apodizing mask Output: 1D power spectrum accounted for w2 from 0 to 10000 """ pmap = enmap.pixsizemap(map_list[0].shape, map_list[0].wcs) cl_ab = [] n = len(map_list) #calculate the coadd maps if a != b: coadd_a = coadd_mapnew(map_list, ivar_list, a) coadd_b = coadd_mapnew(map_list, ivar_list, b) else: coadd_a = coadd_mapnew(map_list, ivar_list, a) for i in range(n): print(i) if a != b: d_a = map_list[i][a] - coadd_a noise_a = d_a * np.sqrt(ivar_eff(i, ivar_list) / pmap) * mask alm_a = cs.map2alm(noise_a, lmax=10000) d_b = map_list[i][b] - coadd_b noise_b = d_b * np.sqrt(ivar_eff(i, ivar_list) / pmap) * mask alm_b = cs.map2alm(noise_b, lmax=10000) cls = hp.alm2cl(alm_a, alm_b) cl_ab.append(cls) else: d_a = map_list[i][a] - coadd_a noise_a = d_a * np.sqrt(ivar_eff(i, ivar_list) / pmap) * mask print("generating alms") alm_a = cs.map2alm(noise_a, lmax=10000) cls = hp.alm2cl(alm_a) cl_ab.append(cls) cl_ab = np.array(cl_ab) sqrt_ivar = np.sqrt(ivar_eff(0, ivar_list) / pmap) mask_ivar = sqrt_ivar * 0 + 1 mask_ivar[sqrt_ivar <= 0] = 0 mask = mask * mask_ivar mask[mask <= 0] = 0 w2 = np.sum((mask**2) * pmap) / np.pi / 4. power = 1 / n / (n - 1) * np.sum(cl_ab, axis=0) ls = np.arange(len(power)) power[~np.isfinite(power)] = 0 power = rolling_average(power, N) bins = np.arange(len(power)) power = maps.interp(bins, power)(ls) return power / w2
def generate_sim(ivar_list, cls, lmax, seed): """ Input: ivar_list: list of inverse variance maps cls: flattened 1D power spectrum Pab lmax:maximum multipole to generate the simulated maps seed: currently a number, need to fix this. Returns: list of sumulated maps. """ shape = ivar_list[0].shape wcs = ivar_list[0].wcs pmap = enmap.pixsizemap(shape, wcs) k = len(ivar_list) sim_maplist = [] for i in range(len(ivar_list)): sim_map = np.sqrt(k) * cs.rand_map( shape, wcs, cls, lmax, spin=0, seed=seed + i) / (np.sqrt( ivar_eff(i, ivar_list) / pmap)) sim_map[~np.isfinite(sim_map)] = 0 sim_maplist.append(sim_map) return sim_maplist
def check_simulation(a, b, map_list, sim_list, ivar_list, mask): """ Check whether simulated power spectrum P_{ab} is consistent with data. Returns list of (split_sim-coadd,split_data-coadd) weighted by the mask*effective_ivar. """ shape = ivar_list[0].shape wcs = ivar_list[0].wcs pmap = enmap.pixsizemap(shape, wcs) sim_coadd = [] data_coadd = [] for i in range(len(sim_list)): dsim = sim_list[i] - coadd_map(sim_list, ivar_list) dsim = dsim * mask * ivar_eff(i, ivar_list) / pmap testalm = cs.map2alm(dsim, lmax=10000) testalm = testalm.astype(np.complex128) testcl = hp.alm2cl(testalm) sim_coadd.append(testcl) if a == b: for i in range(len(map_list)): dataco = map_list[i][a] - coadd_mapnew(map_list, ivar_list, a) dataco = dataco * mask * ivar_eff(i, ivar_list) / pmap testalm = cs.map2alm(dataco, lmax=10000) testalm = testalm.astype(np.complex128) testcl = hp.alm2cl(testalm) data_coadd.append(testcl) else: for i in range(len(map_list)): data_a = map_list[i][a] - coadd_mapnew(map_list, ivar_list, a) data_a = data_a * mask * ivar_eff(i, ivar_list) / pmap data_b = map_list[i][b] - coadd_mapnew(map_list, ivar_list, b) data_b = data_b * mask * ivar_eff(i, ivar_list) / pmap testalm_a = cs.map2alm(data_a, lmax=10000) testalm_a = testalm_a.astype(np.complex128) testalm_b = cs.map2alm(data_b, lmax=10000) testalm_b = testalm_b.astype(np.complex128) testcl = hp.alm2cl(testalm_a, testalm_b) data_coadd.append(testcl) sim_coadd = np.array(sim_coadd) data_coadd = np.array(data_coadd) return (sim_coadd, data_coadd)
def get_poisson_srcs_alms(self, set_idx, sim_num, patch, alm_shape, oshape, owcs): def deltaTOverTcmbToJyPerSr(freqGHz, T0=2.726): """ @brief the function name is self-eplanatory @return the converstion factor stolen from Flipper -- van engelen """ kB = 1.380658e-16 h = 6.6260755e-27 c = 29979245800. nu = freqGHz * 1.e9 x = h * nu / (kB * T0) cNu = 2 * (kB * T0)**3 / (h**2 * c**2) * x**4 / (4 * (np.sinh(x / 2.))**2) cNu *= 1e23 return cNu TCMB_uk = 2.72e6 if oshape[0] > 3: #then this is a multichroic array, and sadly we only have this at 150 GHz for now raise Exception('get_poisson_srcs_alms only implemented for 150 GHz so far ' \ + '(that is the model we currently have for radio sources) ') else: freq_ghz = 148 #ideally this RNG stuff would be defined in a central place to #avoid RNG collisions. Old version is currently commented out at top of #simgen.py templ = self.get_template(patch, shape=oshape, wcs=owcs) templ[:] = 0 seed = seedgen.get_poisson_seed(set_idx, sim_num) np.random.seed(seed=seed) #Wasn't sure how to codify this stuff outside this routine - hardcoded for now S_min_Jy = .001 S_max_Jy = .015 tucci = np.loadtxt( os.path.join(os.path.dirname(os.path.abspath(__file__)), '../data/ns_148GHz_modC2Ex.dat')) S = tucci[:, 0] dS = S[1:] - S[0:-1] dS = np.append(dS, [0.]) dNdS = tucci[:, 1] mean_numbers_per_patch = dNdS * enmap.area(templ.shape, templ.wcs) * dS numbers_per_fluxbin = np.random.poisson(mean_numbers_per_patch) #note pixel areas not constant for pixell maps pixel_areas = enmap.pixsizemap(templ.shape, templ.wcs) for si, fluxval in enumerate(S[S <= S_max_Jy]): xlocs = np.random.randint(templ.shape[-1], size=numbers_per_fluxbin[si]) ylocs = np.random.randint(templ.shape[-2], size=numbers_per_fluxbin[si]) #add the value in jy / sr, i.e. divide by the solid angle of a pixel. templ[0, ylocs, xlocs] += fluxval / pixel_areas[ylocs, xlocs] map_factor = TCMB_uk / deltaTOverTcmbToJyPerSr(freq_ghz) templ *= map_factor #GET ALMs output = curvedsky.map2alm(templ[0], lmax=hp.Alm.getlmax(alm_shape[0])) return output
deg = 25. px = 2.0 shape,wcs = maps.rect_geometry(width_deg=deg,px_res_arcmin=px,proj='plain') modlmap = enmap.modlmap(shape,wcs) ymap,xmap = enmap.posmap(shape,wcs) omap = np.sin(ymap/np.pi*100) + np.cos(xmap/np.pi*100) mfact = 10 afact = 20 rms = (omap - omap.min())*mfact + afact # io.hplot(rms,colorbar=True) pmap = enmap.pixsizemap(shape,wcs) ivar = maps.ivar(shape,wcs,rms,ipsizemap=pmap) # io.hplot(ivar,colorbar=True) my_tasks = range(nsims) theory = cosmology.default_theory() cov = theory.lCl('TT',modlmap) mgen = maps.MapGen((1,)+shape,wcs,cov=cov[None,None]) fwhm = 1.5 wnoise = 40. kbeam = maps.gauss_beam(modlmap,fwhm) feed_dict = {}
def get_maps(self, rot_angle1, rot_angle2, compts=None, use_sht=True, ret_alm=True, transfer=None, load_processed=False, save_processed=False, flux_cut=None): if compts is None: compts = self.compts shape, wcs = self.geometry nshape = (len(compts),) + shape[-2:] ret = enmap.zeros(nshape, wcs) if load_processed and not ret_alm: for i, compt_idx in enumerate(compts): input_file = self.get_fits_path(self.processed_dir, rot_angle1, rot_angle2, compt_idx) print("loading", input_file) temp = enmap.read_map(input_file) ret[i, ...] = enmap.extract(temp, shape, wcs).copy() del temp return ret else: for i, compt_idx in enumerate(compts): if "pts" not in compt_idx: input_file = self.get_fits_path(self.input_dir, rot_angle1, rot_angle2, compt_idx) print("loading", input_file) alm = np.complex128(hp.read_alm(input_file, hdu=(1))) ret[i, ...] = curvedsky.alm2map(alm, enmap.zeros(nshape[1:], wcs)) else: input_file = self.get_fits_path(self.input_dir, rot_angle1, rot_angle2, compt_idx, fits_type="enmap") print("loading", input_file) temp = enmap.read_map(input_file) ret[i, ...] = enmap.extract(temp, shape, wcs).copy() del temp alms = None if transfer is not None: l, f = transfer interp_func = scipy.interpolate.interp1d(l, f, bounds_error=False, fill_value=0.) if use_sht: l_intp = np.arange(self.lmax + 1) f_int = interp_func(l_intp) alms = curvedsky.map2alm(ret, lmax=self.lmax, spin=0) for i in range(len(compts)): alms[i] = hp.almxfl(alms[i], f_int) ret = curvedsky.alm2map(alms, ret, spin=0) else: ftmap = enmap.fft(ret) f_int = interp_func(enmap.modlmap(shape, wcs).ravel()) ftmap = ftmap * np.reshape(f_int, (shape[-2:])) ret = enmap.ifft(ftmap).real; del ftmap if save_processed: raise NotImplemented() if flux_cut is not None: flux_map = flux_cut / enmap.pixsizemap(shape, wcs) flux_map *= 1e-3 * jysr2thermo(148) for i, compt_idx in enumerate(compts): if "pts" not in compt_idx: continue loc = np.where(ret[i] > flux_map) ret[i][loc] = 0. del flux_map if ret_alm and alms is None: alms = curvedsky.map2alm(ret, lmax=self.lmax, spin=0) return ret if not ret_alm else (ret, alms)
def get_maps(self, rot_angle1, rot_angle2, compts=None, use_sht=True, ret_alm=True, transfer=None, load_processed=False, save_processed=False, flux_cut=None): if compts is None: compts = self.compts shape, wcs = self.geometry nshape = (len(compts),) + shape[-2:] ret = enmap.zeros(nshape, wcs) if load_processed and not ret_alm: for i, compt_idx in enumerate(compts): input_file = self.get_fits_path(self.processed_dir, rot_angle1, rot_angle2, compt_idx) print("loading", input_file) temp = enmap.read_map(input_file) ret[i, ...] = enmap.extract(temp, shape, wcs).copy() del temp return ret else: for i, compt_idx in enumerate(compts): input_file = self.get_fits_path(self.input_dir, rot_angle1, rot_angle2, compt_idx) print("loading", input_file) alm = np.complex128(hp.read_alm(input_file, hdu=(1))) ret[i, ...] = curvedsky.alm2map(alm, enmap.zeros(nshape[1:], wcs)) del alm if compt_idx in self.highflux_cats: print("adding high flux cats") hiflux_cat = np.load(self.get_highflux_cat_path(compt_idx)) hiflux_cat[:, :2] = car2hp_coords(hiflux_cat[:, :2]) mat_rot, _, _ = hp.rotator.get_rotation_matrix( (rot_angle1 * utils.degree * -1, rot_angle2 * utils.degree, 0)) uvec = hp.ang2vec(hiflux_cat[:, 0], hiflux_cat[:, 1]) rot_vec = np.inner(mat_rot, uvec).T temppos = hp.vec2ang(rot_vec) rot_pos = np.zeros(hiflux_cat[:, :2].shape) rot_pos[:, 0] = temppos[0] rot_pos[:, 1] = temppos[1] rot_pos = hp2car_coords(rot_pos) del temppos rot_pix = np.round(enmap.sky2pix(nshape[-2:], wcs, rot_pos.T).T).astype(np.int) loc = np.where((rot_pix[:, 0] >= 0) & (rot_pix[:, 0] < nshape[-2]) & (rot_pix[:, 1] >= 0.) & ( rot_pix[:, 1] < nshape[-1])) hiflux_cat = hiflux_cat[loc[0], 2] rot_pix = rot_pix[loc[0], :] hiflux_map = enmap.zeros(nshape[-2:], wcs) hiflux_map[rot_pix[:, 0], rot_pix[:, 1]] = hiflux_cat if flux_cut is not None: tmin = flux_cut * 1e-3 * jysr2thermo(148) loc = np.where(hiflux_map > tmin) hiflux_map[loc] = 0 hiflux_map = hiflux_map / enmap.pixsizemap(shape, wcs) ret[i, ...] = ret[i, ...] + hiflux_map del hiflux_map alms = None if transfer is not None: l, f = transfer interp_func = scipy.interpolate.interp1d(l, f, bounds_error=False, fill_value=0.) if use_sht: l_intp = np.arange(self.lmax + 1) f_int = interp_func(l_intp) alms = curvedsky.map2alm(ret, lmax=self.lmax, spin=0) for i in range(len(compts)): alms[i] = hp.almxfl(alms[i], f_int) ret = curvedsky.alm2map(alms, ret, spin=0) else: ftmap = enmap.fft(ret) f_int = interp_func(enmap.modlmap(shape, wcs).ravel()) ftmap = ftmap * np.reshape(f_int, (shape[-2:])) ret = enmap.ifft(ftmap).real; del ftmap if save_processed: raise NotImplemented() if ret_alm and alms is None: alms = curvedsky.map2alm(ret, lmax=self.lmax, spin=0) return ret if not ret_alm else (ret, alms)