import healpy as hp
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import astropy.units as u
hp.disable_warnings()
In this third notebook, we will handle a case of not-uniform and partial sky coverage.
# Number based on Simons Observatory SAT UHF1 array of detectors
= 10. * u.Unit("uK * sqrt(s)") net
5 years with a efficiency of 20%:
= 5 * u.year * .2 integration_time_total
Download a hitmap
We can download a simulated hitmap for a Simons Observatory band, for now however, we assume a uniform coverage.
= "https://portal.nersc.gov/project/sobs/so_mapsims_data/v0.2/healpix/ST0_UHF1_01_of_20.nominal_telescope_all_time_all_hmap.fits.gz" hitmap_url
!wget $hitmap_url
--2020-12-11 10:35:42-- https://portal.nersc.gov/project/sobs/so_mapsims_data/v0.2/healpix/ST0_UHF1_01_of_20.nominal_telescope_all_time_all_hmap.fits.gz
Resolving portal.nersc.gov (portal.nersc.gov)... 128.55.206.24, 128.55.206.26
Connecting to portal.nersc.gov (portal.nersc.gov)|128.55.206.24|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3212515 (3.1M) [application/x-gzip]
Saving to: ‘ST0_UHF1_01_of_20.nominal_telescope_all_time_all_hmap.fits.gz.10’
ST0_UHF1_01_of_20.n 100%[===================>] 3.06M --.-KB/s in 0.1s
2020-12-11 10:35:43 (30.0 MB/s) - ‘ST0_UHF1_01_of_20.nominal_telescope_all_time_all_hmap.fits.gz.10’ saved [3212515/3212515]
= hp.read_map("ST0_UHF1_01_of_20.nominal_telescope_all_time_all_hmap.fits.gz") hitmap
/= hitmap.max() hitmap
hp.mollview(hitmap)
Generic partial sky survey
We have now a sky coverage which not uniform
= 512
nside = hp.nside2npix(nside) npix
= hitmap / hitmap.sum() * integration_time_total.to(u.s) hitmap
= hitmap.value.copy()
hitmap_plot == 0] = hp.UNSEEN hitmap_plot[hitmap
=hitmap.unit) hp.mollview(hitmap_plot, unit
= \
variance_per_pixel **2 / hitmap).decompose() (net
/home/zonca/zonca/p/software/healpy/healpyvenv/lib/python3.7/site-packages/astropy/units/quantity.py:477: RuntimeWarning: divide by zero encountered in true_divide
result = super().__array_ufunc__(function, method, *arrays, **kwargs)
= 0 variance_per_pixel[np.isinf(variance_per_pixel)]
= np.random.normal(scale = np.sqrt(variance_per_pixel),
m =len(variance_per_pixel)) * np.sqrt(variance_per_pixel).unit size
max() variance_per_pixel.
\(4.51983 \times 10^{-7} \; \mathrm{K^{2}}\)
==0] = hp.UNSEEN m.value[hitmap
= m.to(u.uK) m
==0] = hp.UNSEEN m.value[hitmap
=m.unit, min=-10, max=10, title="White noise map") hp.mollview(m, unit
Power spectrum
= hp.mask_good(m).sum()/len(m) sky_fraction
= hp.anafast(m) / sky_fraction cl
100:].mean() cl[
0.0044214096150382255
= hp.nside2pixarea(nside) pixel_area
= (variance_per_pixel[variance_per_pixel>0].mean() * pixel_area).to(u.uK**2) white_noise_cl
= 1.5341266e-5 * u.uK**2 white_noise_cl_uniform
=(6,4))
plt.figure(figsize="Map power spectrum", alpha=.7)
plt.loglog(cl, label0, len(cl), color="blue",
plt.hlines(white_noise_cl.value, ="White noise level")
label0, len(cl),
plt.hlines(white_noise_cl_uniform.value, ="White noise level uniform")
label"Fullsky white noise spectrum")
plt.title("$\ell$")
plt.xlabel("$C_\ell [\mu K ^ 2]$"); plt.ylabel(
sky_fraction
0.38526121775309247
Pixel weighting in the power spectrum
When we have un-uniform noise across the map, it is advantageous to weight the pixels differently before taking the power spectrum in order to downweight the noisiest pixels.
If we weight by the square root of the number of hits per pixels, then we are normalizing the standard deviation per pixel to be the same across all pixels, in fact we recover the same noise level we had when we were spreading the hits uniformly in the sky patch.
However, the optimal is actually to weight by the inverse variance, which means to weight by the hitmap, to estimate the value expected for this we need to weight the variance by the square of the hitmap (variance is in power so weighting the map by a quantity is equivalent to weighting the variance by its square).
= hp.anafast(m * np.sqrt(hitmap)) / np.mean(hitmap) cl_apodized
= hp.anafast(m * hitmap) / np.mean(hitmap**2) cl_apodized_inv_variance
100:].mean() / white_noise_cl_uniform.value cl_apodized_inv_variance[
\(0.49056891 \; \mathrm{\frac{1}{s^{2}}}\)
/ white_noise_cl_uniform white_noise_cl
\(291.08959 \; \mathrm{}\)
white_noise_cl
\(0.0044656828 \; \mathrm{\mu K^{2}}\)
white_noise_cl_uniform
\(1.5341266 \times 10^{-5} \; \mathrm{\mu K^{2}}\)
=hitmap) * pixel_area * 1e12 np.average(variance_per_pixel, weights
\(1.5341266 \times 10^{-5} \; \mathrm{K^{2}}\)
= np.average(variance_per_pixel, weights=hitmap**2) * pixel_area * 1e12 white_noise_cl_inv_variance
=(10,6))
plt.figure(figsize="White noise equally weighted", alpha=.7)
plt.loglog(cl, label0, len(cl), color="blue", ls=":",
plt.hlines(white_noise_cl.value, ="White noise level equally weighted")
label
="White noise inverse weighted with stddev", alpha=.7)
plt.loglog(cl_apodized, label
0, len(cl), color="red", ls=":",
plt.hlines(white_noise_cl_uniform.value, ="White noise level for map with uniform hits")
label
="White noise inverse weighted with variance", alpha=.7)
plt.loglog(cl_apodized_inv_variance, label0, len(cl), color="darkgreen", ls=":",
plt.hlines(white_noise_cl_inv_variance.value, ="White noise level inverse weighted")
label"Fullsky white noise spectrum")
plt.title(
plt.legend()"$\ell$")
plt.xlabel("$C_\ell [\mu K ^ 2]$"); plt.ylabel(