def gal2equ(in_file, out_file, smooth, eulers=None): e2g = np.array([[-0.054882486, -0.993821033, -0.096476249], [ 0.494116468, -0.110993846, 0.862281440], [-0.867661702, -0.000346354, 0.497154957]]) # intrinsic rotation g2e = np.linalg.inv(e2g) eps = 23.452294 - 0.0130125 - 1.63889E-6 + 5.02778E-7 eps = eps * np.pi / 180. e2q = np.array([[1., 0. , 0. ], [0., np.cos( eps ), -1. * np.sin( eps )], [0., np.sin( eps ), np.cos( eps ) ]]) g2q = np.dot(e2q , g2e) psi = np.arctan2(g2q[1,2],g2q[0,2]) theta = np.arccos(g2q[2,2]) phi = np.arctan2(g2q[2,1],-g2q[2,0]) # deduced from zyz rotation matrix fwhm = smooth*((2*np.pi)/360) alms = hp.read_alm(in_file) hp.smoothalm(alms, fwhm=fwhm) if eulers == None: hp.rotate_alm(alms, phi, theta, psi) # reverse rotation order -> extrinsic rotation print('Euler angles (zyz) = ', str(np.rad2deg(phi)), str(np.rad2deg(theta)), str(np.rad2deg(psi))) else: eulers = np.deg2rad(eulers) hp.rotate_alm(alms, eulers[0], eulers[1], eulers[2]) print('Euler angles (zyz) = ', str(np.rad2deg(eulers[0])), str(np.rad2deg(eulers[1])), str(np.rad2deg(eulers[2]))) print(e2q) hp.write_alm(out_file, alms)
def apply_smoothing_and_coord_transform(input_map, fwhm=None, rot=None, lmax=None, map_dist=None): """Apply smoothing and coordinate rotation to an input map it applies the `healpy.smoothing` Gaussian smoothing kernel if `map_dist` is None, otherwise applies distributed smoothing with `libsharp`. In the distributed case, no rotation is supported. Parameters ---------- input_map : ndarray Input map, of shape `(3, npix)` This is assumed to have no beam at this point, as the simulated small scale tempatle on which the simulations are based have no beam. fwhm : astropy.units.Quantity Full width at half-maximum, defining the Gaussian kernels to be applied. rot: hp.Rotator Apply a coordinate rotation give a healpy `Rotator`, e.g. if the inputs are in Galactic, `hp.Rotator(coord=("G", "C"))` rotates to Equatorial Returns ------- smoothed_map : np.ndarray Array containing the smoothed sky """ if map_dist is None: nside = hp.get_nside(input_map) alm = hp.map2alm(input_map, lmax=lmax, use_pixel_weights=True if nside > 16 else False) if fwhm is not None: hp.smoothalm(alm, fwhm=fwhm.to_value(u.rad), verbose=False, inplace=True, pol=True) if rot is not None: rot.rotate_alm(alm, inplace=True) smoothed_map = hp.alm2map(alm, nside=nside, verbose=False, pixwin=False) else: assert (rot is None) or ( rot.coordin == rot.coordout), "No rotation supported in distributed smoothing" smoothed_map = mpi.mpi_smoothing(input_map, fwhm, map_dist) if hasattr(input_map, "unit"): smoothed_map <<= input_map.unit return smoothed_map
def test_scan_spole_bin(self): ''' Perform a (low resolution) scan, bin and compare to input. ''' mlen = 10 * 60 rot_period = 120 mmax = 2 ra0=-10 dec0=-57.5 fwhm = 200 nside = 256 az_throw = 10 scs = ScanStrategy(duration=mlen, sample_rate=10, location='spole') # Create a 1 x 2 square grid of Gaussian beams. scs.create_focal_plane(nrow=1, ncol=2, fov=4, lmax=self.lmax, fwhm=fwhm) # Allocate and assign parameters for mapmaking. scs.allocate_maps(nside=nside) # set instrument rotation. scs.set_instr_rot(period=rot_period, angles=[68, 113, 248, 293]) # Set elevation stepping. scs.set_el_steps(rot_period, steps=[0, 2, 4]) # Set HWP rotation. scs.set_hwp_mod(mode='continuous', freq=3.) # Generate timestreams, bin them and store as attributes. scs.scan_instrument_mpi(self.alm, verbose=0, ra0=ra0, dec0=dec0, az_throw=az_throw, scan_speed=2., nside_spin=nside, max_spin=mmax) # Solve for the maps maps, cond = scs.solve_for_map(fill=np.nan) hp.smoothalm(self.alm, fwhm=np.radians(fwhm/60.), verbose=False) maps_raw = np.asarray(hp.alm2map(self.alm, nside, verbose=False)) cond[~np.isfinite(cond)] = 10 np.testing.assert_array_almost_equal(maps_raw[0,cond<2.5], maps[0,cond<2.5], decimal=10) np.testing.assert_array_almost_equal(maps_raw[1,cond<2.5], maps[1,cond<2.5], decimal=10) np.testing.assert_array_almost_equal(maps_raw[2,cond<2.5], maps[2,cond<2.5], decimal=10)
def add_systematics(self, err=None, sigma=None, Sigma=None, nside=None): F = err.get_formatted_like(self.harpix).get_data(mul_sr=True) self.Flist.append(F) if nside > 1: # Use healpy to do convolution lmax = 3 * nside - 1 # default from hp.smoothing Nalm = hp.Alm.getsize(lmax) G = np.zeros(Nalm, dtype='complex128') H = hp.smoothalm(np.ones(Nalm), sigma=np.deg2rad(sigma), inplace=False, verbose=False) npix = hp.nside2npix(nside) m = np.zeros(npix) m[10] = 1 M = hp.alm2map(hp.map2alm(m) * H, nside, verbose=False) G += H / max(M) T = harp.get_trans_matrix(self.harpix, nside, nest=False, counts=True) def X1(x): z = harp.trans_data(T, x) b = np.zeros_like(z) if self.harpix.dims is not (): for i in range(self.harpix.dims[0]): alm = hp.map2alm(z[:, i]) alm *= G b[:, i] = hp.alm2map(alm, nside, verbose=False) else: alm = 1e30 * hp.map2alm(z / 1e30, iter=0) # Older but faster routine alm *= G b = hp.alm2map(alm, nside, verbose=False) return harp.trans_data(T.T, b) else: vec = self.harpix.get_vec() N = len(self.harpix.data) M = np.zeros((N, N)) #corr = 2.**(self.harpix.order-2) sigma2 = np.deg2rad(sigma)**2 for i in range(N): dist = hp.rotator.angdist(vec[:, i], vec) M[i] = np.exp(-dist**2 / 2 / sigma2) #for i in range(N): # for j in range(N): # pass # #M[i,j] *= (corr[i]*corr[j])**2 def X1(x): return M.dot(x) def X0(x): if Sigma is not None: x = Sigma.dot(x.T).T return x self.Xlist.append([X0, X1])
def get_emission( self, freqs: u.GHz, fwhm: [u.arcmin, None] = None, weights=None, output_units=u.uK_RJ, ): """Return map in uK_RJ at given frequency or array of frequencies Parameters ---------- freqs : list or ndarray Frequency or frequencies in GHz at which compute the signal fwhm : float (optional) Smooth the input alms before computing the signal, this can only be used if the class was initialized with `precompute_output_map` to False. output_units : str Output units, as defined in `pysm.convert_units`, by default this is "uK_RJ" as expected by PySM. Returns ------- output_maps : ndarray Output maps array with the shape (num_freqs, 1 or 3 (I or IQU), npix) """ freqs = pysm.utils.check_freq_input(freqs) weights = pysm.utils.normalize_weights(freqs, weights) try: output_map = self.output_map except AttributeError: if fwhm is None: alm = self.alm else: alm = hp.smoothalm(self.alm, fwhm=fwhm.to_value(u.radian), pol=True, inplace=False) output_map = self.compute_output_map(alm) output_units = u.Unit(output_units) assert output_units in [u.uK_RJ, u.uK_CMB] if output_units == u.uK_RJ: convert_to_uK_RJ = (np.ones(len(freqs), dtype=np.double) * u.uK_CMB).to_value( u.uK_RJ, equivalencies=u.cmb_equivalencies(freqs * u.GHz)) if len(freqs) == 1: scaling_factor = convert_to_uK_RJ[0] else: scaling_factor = np.trapz(convert_to_uK_RJ * weights, x=freqs) return output_map.value * scaling_factor << u.uK_RJ elif output_units == output_map.unit: return output_map
def smooth_and_rotate_map(input_map, lmax=None, fwhm=None, rot=None): nside = hp.get_nside(input_map) alm = hp.map2alm(input_map, lmax=lmax, use_pixel_weights=True if nside > 16 else False) if fwhm is not None: hp.smoothalm(alm, fwhm=fwhm.to_value(u.rad), verbose=False, inplace=True, pol=True) if rot is not None: alm = rot.rotate_alm(alm) smoothed_map = hp.alm2map(alm, nside=nside, verbose=False, pixwin=False) if hasattr(input_map, "unit"): smoothed_map <<= input_map.unit return smoothed_map
def wiener_filter(almarr): lmax = hp.Alm.getlmax(len(almarr)) l, m = hp.Alm.getlm(lmax=lmax) noise_table = pd.read_csv('maps/nlkk.dat', delim_whitespace=True, header=None) cl_plus_nl = np.array(noise_table[2]) nl = np.array(noise_table[1]) cl = cl_plus_nl - nl wien_factor = cl/cl_plus_nl almarr = hp.smoothalm(almarr, beam_window=wien_factor) return almarr
def smoothtest(): nside = 64 sigma = 30 lmax = 3 * nside - 1 # default from hp.smoothing lmax += 10 Nalm = hp.Alm.getsize(lmax) H = hp.smoothalm(np.ones(Nalm), sigma=np.deg2rad(sigma), inplace=False) npix = hp.nside2npix(nside) m = np.zeros(npix) m[1000] = 1 M = hp.alm2map(hp.map2alm(m, lmax=lmax) * H, nside, lmax=lmax) G = H / max(M) m *= 0 m[0] = 1 I = hp.alm2map(hp.map2alm(m, lmax=lmax) * G, nside, lmax=lmax) print max(I) hp.mollview(I) plt.savefig('test.eps')
def klm_2_product(klmname, width, maskname, nsides, lmin, subtract_mf=False, writename=None): # read in planck alm convergence data planck_lensing_alm = hp.read_alm(klmname) lmax = hp.Alm.getlmax(len(planck_lensing_alm)) if subtract_mf: mf_alm = hp.read_alm('maps/mf_klm.fits') planck_lensing_alm = planck_lensing_alm - mf_alm # if you want to smooth with a gaussian if width > 0: # transform a gaussian of FWHM=width in real space to harmonic space k_space_gauss_beam = hp.gauss_beam(fwhm=width.to('radian').value, lmax=lmax) # if truncating small l modes if lmin > 0: # zero out small l modes in k-space filter k_space_gauss_beam[:lmin] = 0 # smooth in harmonic space filtered_alm = hp.smoothalm(planck_lensing_alm, beam_window=k_space_gauss_beam) else: # if not smoothing with gaussian, just remove small l modes filtered_alm = zero_modes(planck_lensing_alm, lmin) planck_lensing_map = hp.sphtfunc.alm2map(filtered_alm, nsides, lmax=lmax) # mask map importmask = hp.read_map(maskname) if nsides < 2048: mask_lowres_proper = hp.ud_grade(importmask.astype(float), nside_out=1024).astype(float) finalmask = np.where(mask_lowres_proper == 1., True, False).astype(bool) else: finalmask = importmask.astype(np.bool) # set mask, invert smoothed_masked_map = hp.ma(planck_lensing_map) smoothed_masked_map.mask = np.logical_not(finalmask) if writename: hp.write_map('%s.fits' % writename, smoothed_masked_map.filled(), overwrite=True, dtype=np.single) return smoothed_masked_map.filled()
def apply_smoothing(skies, fwhms, coord="G", lmax=None, mpi_comm=None): """ Method to apply smoothing to a set of simulations. This currently applies only the `healpy.smoothing` Gaussian smoothing kernel, but will be updated with a more general functionality. Note: this method may be overridden by child classes which require more complicated implementations of smoothing, as long as they are compatible with the input and output of this template. Parameters ---------- skies: ndarray Numpy array of shape (nchannels, 3, npix), containing the unsmoothed skies. This is assumed to have no beam at this point, as the simulated small scale tempalte on which the simulations are based have no beam. fwhms: list(float) List of full width at half-maixima in arcminutes, defining the Gaussian kernels to be applied. Returns ------- ndarray Array containing the smoothed skies. """ if isinstance(fwhms, list): fwhms = np.array(fwhms) * u.arcmin elif isinstance(fwhms, np.ndarray): fwhms *= u.arcmin else: fwhms = np.array([fwhms]) * u.arcmin try: assert fwhms.ndim < 2 except AssertionError: print("""Check that FWHMs is given as a 1D list, 1D array. of float""") nside = hp.get_nside(skies[0]) out = [] for sky, fwhm in zip(skies, fwhms): if mpi_comm is None: alm = hp.map2alm(sky, lmax=lmax, use_pixel_weights=True, iter=1) hp.smoothalm( alm, fwhm=fwhm.to_value(u.rad), verbose=False, inplace=True, pol=True, ) if coord != "G": rot = hp.Rotator(coord=["G", coord]) rot.rotate_alm(alm, inplace=True) smoothed_sky = hp.alm2map(alm, nside=nside, verbose=False, pixwin=False) else: smoothed_sky = mpi_smoothing(sky) out.append(smoothed_sky) return np.array(out)
def test_ghosts(lmax=700, mmax=5, fwhm=43, ra0=-10, dec0=-57.5, az_throw=50, scan_speed=2.8, rot_period=4.5 * 60 * 60, hwp_mode=None): ''' Similar test to `scan_bicep`, but includes reflected ghosts Simulates a 24h BICEP2-like scan strategy using a random LCDM realisation and a 3 x 3 grid of Gaussian beams pairs. Bins tods into maps and compares to smoothed input maps (no pair- differencing). MPI-enabled. Keyword arguments --------- lmax : int, bandlimit (default : 700) mmax : int, assumed azimuthal bandlimit beams (symmetric in this example so 2 would suffice) (default : 5) fwhm : float, The beam FWHM in arcmin (default : 40) ra0 : float, Ra coord of centre region (default : -10) dec0 : float, (default : -57.5) Ra coord of centre region az_throw : float, Scan width in azimuth (in degrees) (default : 50) scan_speed : float, Scan speed in deg/s (default : 1) rot_period : float, The instrument rotation period in sec (default : 600) hwp_mode : str, None HWP modulation mode, either "continuous", "stepped" or None. Use freq of 1 or 1/10800 Hz respectively (default : None) ''' mlen = 24 * 60 * 60 # hardcoded mission length # Create LCDM realization ell, cls = get_cls() np.random.seed(25) # make sure all MPI ranks use the same seed alm = hp.synalm(cls, lmax=lmax, new=True, verbose=True) # uK b2 = ScanStrategy( mlen, # mission duration in sec. sample_rate=12.01, # sample rate in Hz location='spole') # Instrument at south pole # Create a 3 x 3 square grid of Gaussian beams b2.create_focal_plane(nrow=3, ncol=3, fov=5, lmax=lmax, fwhm=fwhm) # Create reflected ghosts for every detector # We create two ghosts per detector. They overlap # but have different fwhm. First ghost is just a # scaled down version of the main beam, the second # has a much wider Gaussian shape. # After this initialization, the code takes # the ghosts into account without modifications b2.create_reflected_ghosts(b2.beams, amplitude=0.01, ghost_tag='ghost_1', dead=False) b2.create_reflected_ghosts(b2.beams, amplitude=0.01, fwhm=100, ghost_tag='ghost_2', dead=False) # calculate tods in two chunks b2.partition_mission(0.5 * b2.nsamp) # Allocate and assign parameters for mapmaking b2.allocate_maps(nside=256) # set instrument rotation b2.set_instr_rot(period=rot_period, angles=[68, 113, 248, 293]) # Set HWP rotation if hwp_mode == 'continuous': b2.set_hwp_mod(mode='continuous', freq=1.) elif hwp_mode == 'stepped': b2.set_hwp_mod(mode='stepped', freq=1 / (3 * 60 * 60.)) # Generate timestreams, bin them and store as attributes b2.scan_instrument_mpi(alm, verbose=1, ra0=ra0, dec0=dec0, az_throw=az_throw, nside_spin=256, max_spin=mmax) # Solve for the maps maps, cond = b2.solve_for_map(fill=np.nan) # Plotting if b2.mpi_rank == 0: print('plotting results') cart_opts = dict( rot=[ra0, dec0, 0], lonra=[-min(0.5 * az_throw, 90), min(0.5 * az_throw, 90)], latra=[-min(0.375 * az_throw, 45), min(0.375 * az_throw, 45)], unit=r'[$\mu K_{\mathrm{CMB}}$]') # plot rescanned maps plot_iqu(maps, '../scratch/img/', 'rescan_ghost', sym_limits=[250, 5, 5], plot_func=hp.cartview, **cart_opts) # plot smoothed input maps nside = hp.get_nside(maps[0]) hp.smoothalm(alm, fwhm=np.radians(fwhm / 60.), verbose=False) maps_raw = hp.alm2map(alm, nside, verbose=False) plot_iqu(maps_raw, '../scratch/img/', 'raw_ghost', sym_limits=[250, 5, 5], plot_func=hp.cartview, **cart_opts) # plot difference maps for arr in maps_raw: # replace stupid UNSEEN crap arr[arr == hp.UNSEEN] = np.nan diff = maps_raw - maps plot_iqu(diff, '../scratch/img/', 'diff_ghost', sym_limits=[1e+1, 1e-1, 1e-1], plot_func=hp.cartview, **cart_opts) # plot condition number map cart_opts.pop('unit', None) plot_map(cond, '../scratch/img/', 'cond_ghost', min=2, max=5, unit='condition number', plot_func=hp.cartview, **cart_opts) # plot input spectrum cls[3][cls[3] <= 0.] *= -1. dell = ell * (ell + 1) / 2. / np.pi plt.figure() for i, label in enumerate(['TT', 'EE', 'BB', 'TE']): plt.semilogy(ell, dell * cls[i], label=label) plt.legend() plt.ylabel(r'$D_{\ell}$ [$\mu K^2_{\mathrm{CMB}}$]') plt.xlabel(r'Multipole [$\ell$]') plt.savefig('../scratch/img/cls_ghost.png') plt.close()
def scan_atacama(lmax=700, mmax=5, fwhm=40, mlen=48 * 60 * 60, nrow=3, ncol=3, fov=5.0, ra0=[-10, 170], dec0=[-57.5, 0], el_min=45., cut_el_min=False, az_throw=50, scan_speed=1, rot_period=0, hwp_mode='continuous'): ''' Simulates 48h of an atacama-based telescope with a 3 x 3 grid of Gaussian beams pairs. Prefers to scan the bicep patch but will try to scan the ABS_B patch if the first is not visible. Keyword arguments --------- lmax : int bandlimit (default : 700) mmax : int assumed azimuthal bandlimit beams (symmetric in this example so 2 would suffice) (default : 5) fwhm : float The beam FWHM in arcmin (default : 40) mlen : int The mission length [seconds] (default : 48 * 60 * 60) nrow : int Number of detectors along row direction (default : 3) ncol : int Number of detectors along column direction (default : 3) fov : float The field of view in degrees (default : 5.0) ra0 : float, array-like Ra coord of centre region (default : [-10., 85.]) dec0 : float, array-like Ra coord of centre region (default : [-57.5, 0.]) el_min : float Minimum elevation range [deg] (default : 45) cut_el_min: bool If True, excludes timelines where el would be less than el_min az_throw : float Scan width in azimuth (in degrees) (default : 10) scan_speed : float Scan speed in deg/s (default : 1) rot_period : float The instrument rotation period in sec (default : 600) hwp_mode : str, None HWP modulation mode, either "continuous", "stepped" or None. Use freq of 1 or 1/10800 Hz respectively (default : continuous) ''' # hardcoded mission length # Create LCDM realization ell, cls = get_cls() np.random.seed(25) # make sure all MPI ranks use the same seed alm = hp.synalm(cls, lmax=lmax, new=True, verbose=True) # uK ac = ScanStrategy( mlen, # mission duration in sec. sample_rate=12.01, # sample rate in Hz location='atacama') # Instrument at south pole # Create a 3 x 3 square grid of Gaussian beams ac.create_focal_plane(nrow=nrow, ncol=ncol, fov=fov, lmax=lmax, fwhm=fwhm) # calculate tods in two chunks ac.partition_mission(0.5 * ac.mlen * ac.fsamp) # Allocate and assign parameters for mapmaking ac.allocate_maps(nside=256) # set instrument rotation ac.set_instr_rot(period=rot_period) # Set HWP rotation if hwp_mode == 'continuous': ac.set_hwp_mod(mode='continuous', freq=1.) elif hwp_mode == 'stepped': ac.set_hwp_mod(mode='stepped', freq=1 / (3 * 60 * 60.)) # Generate timestreams, bin them and store as attributes ac.scan_instrument_mpi(alm, verbose=2, ra0=ra0, dec0=dec0, az_throw=az_throw, nside_spin=256, el_min=el_min, cut_el_min=cut_el_min, create_memmap=True) # Solve for the maps maps, cond = ac.solve_for_map(fill=np.nan) # Plotting if ac.mpi_rank == 0: print('plotting results') img_out_path = '../scratch/img/' moll_opts = dict(unit=r'[$\mu K_{\mathrm{CMB}}$]') # plot rescanned maps plot_iqu(maps, img_out_path, 'rescan_atacama', sym_limits=[250, 5, 5], plot_func=hp.mollview, **moll_opts) # plot smoothed input maps nside = hp.get_nside(maps[0]) hp.smoothalm(alm, fwhm=np.radians(fwhm / 60.), verbose=False) maps_raw = hp.alm2map(alm, nside, verbose=False) plot_iqu(maps_raw, img_out_path, 'raw_atacama', sym_limits=[250, 5, 5], plot_func=hp.mollview, **moll_opts) # plot difference maps for arr in maps_raw: # replace stupid UNSEEN crap arr[arr == hp.UNSEEN] = np.nan diff = maps_raw - maps plot_iqu(diff, img_out_path, 'diff_atacama', sym_limits=[1e-6, 1e-6, 1e-6], plot_func=hp.mollview, **moll_opts) # plot condition number map moll_opts.pop('unit', None) plot_map(cond, img_out_path, 'cond_atacama', min=2, max=5, unit='condition number', plot_func=hp.mollview, **moll_opts) # plot input spectrum cls[3][cls[3] <= 0.] *= -1. dell = ell * (ell + 1) / 2. / np.pi plt.figure() for i, label in enumerate(['TT', 'EE', 'BB', 'TE']): plt.semilogy(ell, dell * cls[i], label=label) plt.legend() plt.ylabel(r'$D_{\ell}$ [$\mu K^2_{\mathrm{CMB}}$]') plt.xlabel(r'Multipole [$\ell$]') plt.savefig('../scratch/img/cls_atacama.png') plt.close() print("Results written to {}".format(os.path.abspath(img_out_path)))
def test_satellite_scan(lmax=700, mmax=2, fwhm=43, ra0=-10, dec0=-57.5, az_throw=50, scan_speed=2.8, hwp_mode=None, alpha=45., beta=45., alpha_period=5400., beta_period=600., delta_az=0., delta_el=0., delta_psi=0., jitter_amp=1.0): ''' Simulates a satellite scan strategy using a random LCDM realisation and a 3 x 3 grid of Gaussian beams pairs. Bins tods into maps and compares to smoothed input maps (no pair- differencing). MPI-enabled. Keyword arguments --------- lmax : int, bandlimit (default : 700) mmax : int, assumed azimuthal bandlimit beams (symmetric in this example so 2 would suffice) (default : 2) fwhm : float, The beam FWHM in arcmin (default : 40) ra0 : float, Ra coord of centre region (default : -10) dec0 : float, (default : -57.5) Ra coord of centre region az_throw : float, Scan width in azimuth (in degrees) (default : 50) scan_speed : float, Scan speed in deg/s (default : 1) hwp_mode : str, None HWP modulation mode, either "continuous", "stepped" or None. Use freq of 1 or 1/10800 Hz respectively (default : None) ''' print('Simulating a satellite...') mlen = 3 * 24 * 60 * 60 # hardcoded mission length # Create LCDM realization ell, cls = get_cls() np.random.seed(25) # make sure all MPI ranks use the same seed alm = hp.synalm(cls, lmax=lmax, new=True, verbose=True) # uK sat = ScanStrategy( mlen, # mission duration in sec. external_pointing=True, # Telling code to use non-standard scanning sample_rate=12.01, # sample rate in Hz location='space') # Instrument at south pole # Create a 3 x 3 square grid of Gaussian beams sat.create_focal_plane(nrow=7, ncol=7, fov=15, lmax=lmax, fwhm=fwhm) # calculate tods in two chunks sat.partition_mission(0.5 * sat.nsamp) # Allocate and assign parameters for mapmaking sat.allocate_maps(nside=256) scan_opts = dict(q_bore_func=sat.satellite_scan, ctime_func=sat.satellite_ctime, q_bore_kwargs=dict(), ctime_kwargs=dict()) # Generate timestreams, bin them and store as attributes sat.scan_instrument_mpi(alm, verbose=1, ra0=ra0, dec0=dec0, az_throw=az_throw, nside_spin=256, max_spin=mmax, **scan_opts) # Solve for the maps maps, cond, proj = sat.solve_for_map(fill=np.nan, return_proj=True) # Plotting if sat.mpi_rank == 0: print('plotting results') cart_opts = dict(unit=r'[$\mu K_{\mathrm{CMB}}$]') # plot rescanned maps plot_iqu(maps, '../scratch/img/', 'rescan_satellite', sym_limits=[250, 5, 5], plot_func=hp.mollview, **cart_opts) # plot smoothed input maps nside = hp.get_nside(maps[0]) hp.smoothalm(alm, fwhm=np.radians(fwhm / 60.), verbose=False) maps_raw = hp.alm2map(alm, nside, verbose=False) plot_iqu(maps_raw, '../scratch/img/', 'raw_satellite', sym_limits=[250, 5, 5], plot_func=hp.mollview, **cart_opts) # plot difference maps for arr in maps_raw: # replace stupid UNSEEN crap arr[arr == hp.UNSEEN] = np.nan diff = maps_raw - maps plot_iqu(diff, '../scratch/img/', 'diff_satellite', sym_limits=[1e-6, 1e-6, 1e-6], plot_func=hp.mollview, **cart_opts) # plot condition number map cart_opts.pop('unit', None) plot_map(cond, '../scratch/img/', 'cond_satellite', min=2, max=5, unit='condition number', plot_func=hp.mollview, **cart_opts) plot_map(proj[0], '../scratch/img/', 'hits_satellite', unit='Hits', plot_func=hp.mollview, **cart_opts)
def idea_jon(): nside_spin = 512 ra0 = 0 dec0 = -90 az_throw = 10 max_spin = 5 fwhm = 32.2 scan_opts = dict(verbose=1, ra0=ra0, dec0=dec0, az_throw=az_throw, nside_spin=nside_spin, max_spin=max_spin, binning=True) lmax = 800 alm = tools.gauss_blm(1e-5, lmax, pol=False) ell = np.arange(lmax + 1) fl = np.sqrt((2 * ell + 1) / 4. / np.pi) hp.almxfl(alm, fl, mmax=None, inplace=True) fm = (-1)**(hp.Alm.getlm(lmax)[1]) alm *= fm alm = tools.get_copol_blm(alm) # create Beam properties and pickle (this is just to test load_focal_plane) import tempfile import shutil import pickle opj = os.path.join blm_dir = os.path.abspath( opj(os.path.dirname(__file__), '../tests/test_data/example_blms')) po_file = opj(blm_dir, 'blm_hp_X1T1R1C8A_800_800.npy') eg_file = opj(blm_dir, 'blm_hp_eg_X1T1R1C8A_800_800.npy') tmp_dir = tempfile.mkdtemp() beam_file = opj(tmp_dir, 'beam_opts.pkl') beam_opts = dict(az=0, el=0, polang=0., btype='Gaussian', name='X1T1R1C8', fwhm=fwhm, lmax=800, mmax=800, amplitude=1., po_file=po_file, eg_file=eg_file) with open(beam_file, 'wb') as handle: pickle.dump(beam_opts, handle, protocol=pickle.HIGHEST_PROTOCOL) # init scan strategy and instrument ss = ScanStrategy( 1., # mission duration in sec. sample_rate=10000, location='spole') ss.allocate_maps(nside=1024) ss.load_focal_plane(tmp_dir, no_pairs=True) # remove tmp dir and contents shutil.rmtree(tmp_dir) ss.set_el_steps(0.01, steps=np.linspace(-10, 10, 100)) # Generate maps with Gaussian beams ss.scan_instrument_mpi(alm, **scan_opts) ss.reset_el_steps() # Solve for the maps maps_g, cond_g = ss.solve_for_map(fill=np.nan) # Generate maps with elliptical Gaussian beams ss.allocate_maps(nside=1024) ss.beams[0][0].btype = 'EG' ss.scan_instrument_mpi(alm, **scan_opts) ss.reset_el_steps() # Solve for the maps maps_eg, cond_eg = ss.solve_for_map(fill=np.nan) # Generate map with Physical Optics beams and plot them ss.allocate_maps(nside=1024) ss.beams[0][0].btype = 'PO' ss.scan_instrument_mpi(alm, **scan_opts) ss.reset_el_steps() # Solve for the maps maps_po, cond_po = ss.solve_for_map(fill=np.nan) # Plotting print('plotting results') cart_opts = dict( #rot=[ra0, dec0, 0], lonra=[-min(0.5 * az_throw, 10), min(0.5 * az_throw, 10)], latra=[-min(0.375 * az_throw, 10), min(0.375 * az_throw, 10)], unit=r'[$\mu K_{\mathrm{CMB}}$]') # plot smoothed input maps nside = hp.get_nside(maps_g[0]) hp.smoothalm(alm, fwhm=np.radians(fwhm / 60.), verbose=False) maps_raw = hp.alm2map(alm, nside, verbose=False) plot_iqu(maps_raw, '../scratch/img/', 'raw_delta', sym_limits=[1, 1, 1], plot_func=hp.cartview, **cart_opts)
def signal(self, nu=[148.], fwhm_arcmin=None, output_units="uK_RJ", **kwargs): """Return map in uK_RJ at given frequency or array of frequencies If nothing is specified for nu, we default to providing an unmodulated map at 148 GHz. The value 148 Ghz does not matter if the output is in uK_RJ. Parameters ---------- nu : list or ndarray Frequency or frequencies in GHz at which compute the signal fwhm_arcmin : float (optional) Smooth the input alms before computing the signal, this can only be used if the class was initialized with `precompute_output_map` to False. output_units : str Output units, as defined in `pysm.convert_units`, by default this is "uK_RJ" as expected by PySM. Returns ------- output_maps : ndarray Output maps array with the shape (num_freqs, 1 or 3 (I or IQU), npix) """ try: nnu = len(nu) except TypeError: nnu = 1 nu = np.array([nu]) try: output_map = self.output_map except AttributeError: if fwhm_arcmin is None: alm = self.alm else: alm = hp.smoothalm( self.alm, fwhm=np.radians(fwhm_arcmin / 60), pol=True, inplace=False ) output_map = self.compute_output_map(alm) # use tile to output the same map for all frequencies out = np.tile(output_map, (nnu, 1, 1)) if self.wcs is not None: out = enmap.enmap(out, self.wcs) out *= ( ( pysm.convert_units( self.input_units, "uK_CMB", self.input_reference_frequency_GHz ) * pysm.convert_units("uK_CMB", output_units, nu) ) .reshape((nnu, 1, 1)) .astype(float) ) # the output of out is always 3D, (num_freqs, IQU, npix), if num_freqs is one # we return only a 2D array. if len(out) == 1: return out[0] else: return out
def hpalmsmooth(_alms): #smooths a given set of alms with a gaussian beam smoother. return hp.smoothalm(_alms, fwhm = 0.0)
""" STEP 4: Spherical harmonic transforms tools: smoothing, smoothalm """ mapa = hp.read_map('COM_CMB_IQU-smica_1024_R2_02_full.fits') hp.mollview(mapa, title='CMB map') pyplot.savefig("mollview_COM_CMB_IQU-smica_1024_R2.02_full.png") mapa_smo = hp.smoothing(mapa, fwhm=np.deg2rad(0.75)) hp.mollview(mapa_smo, title='Smoothed map') pyplot.savefig("mapa_smoothing_ex.png") alm = hp.map2alm(mapa) alm_smo = hp.smoothalm(alm, fwhm=np.deg2rad(0.75)) mapa2_alm_smo = hp.alm2map(alm_smo, 1024) hp.mollview(mapa2_alm_smo, title='Smoothed alm') pyplot.savefig("mapa_smoothalm_ex.png") hp.mollview(mapa2_alm_smo-mapa_smo, title='Difference') #%% """ STEP 5: Spherical harmonic transforms tools: pixwin """ Cls = hp.read_cl('Cls_bestfitLCDM_PLA2_TT_lmax2508.fits')
return em*(2*L-1-em)/2+el # Define parameters nside = 1024 L = 3*nside # should be at least 2*nside, if possible between 3 and 5 nside. lmax = L-1 # just renaming for clarity/consistency with healpy fwhm = 0.5 * np.pi / nside # smoothing size (don't ask how I picked this... arXiv:1306.0005) bl = hp.gauss_beam(fwhm, lmax=lmax, pol=True) plt.plot(bl**2) plt.xlim([0, lmax]) #stop # Construct smoothed and extended masks to keep quasi-leakage-free regions of the sky threshold = 0.99 mask_lm = hp.map2alm(QU_mask, lmax=lmax, pol=False) # scalar transform mask_lm_sm = hp.smoothalm(mask_lm, fwhm=4*fwhm) # extra smoothing of the mask to deal with edges mask_sm = hp.alm2map(mask_lm_sm, nside=1024, lmax=lmax, pol=False) # mask at adequate resolusion mask_sm_t = 1*mask_sm mask_sm_t[mask_sm >= threshold] = 1 mask_sm_t[mask_sm < threshold] = 0 mask_lm_sm2 = hp.map2alm(mask_sm_t, lmax=lmax, pol=False) # scalar transform _ = hp.smoothalm(mask_lm_sm2, fwhm=4*fwhm, inplace=True) # extra smoothing of the mask to deal with edges mask_sm2 = hp.alm2map(mask_lm_sm2, nside=nside, lmax=lmax, pol=False) # mask at adequate resolusion mask = 1*mask_sm2 mask[mask < threshold] = 0 mask[mask > threshold] = 1 # Do EB separation using Healpy, even though there will be leakage near mask KQU_masked_maps = [kappatrue_inputmap*mask_sm, Q_map*mask_sm, U_map*mask_sm] almsnosm = hp.map2alm(KQU_masked_maps, lmax=lmax, pol=True) # Spin transform! [kappatrue_lm, E_lm, B_lm] = hp.smoothalm(almsnosm, fwhm=fwhm) # extra smoothing of the mask to deal with edges