def rotate(self, psi, theta, phi): """ Returns a rotated copy of self. O(lmax^3). :: >>> M = harmonic_sphere_map([[1, 0], [1, 0, 0]], lmin=1) >>> R = M.rotate(0, np.pi, 0); R Brief complex harmonic sphere map with l=1..2 (5 coefficients) >>> np.round(R.to_array(), 4) array([-1.+0.j, -0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]) One can convert multiple maps at once:: TODO write tests """ from healpix import rotate_alm_d self._check_not_pretending() if psi == 0 and theta == 0 and phi == 0: return self.copy() if self.format is not COMPLEX_BRIEF: x = self.to_complex().rotate(psi, theta, phi) if self.format is REAL_FULL: return x.to_real() else: assert False size = self.shape[1:] # Todo: Optimize -- have lmin in complexpacked2complexmatrix out = np.empty((l_to_lm(self.lmax + 1),) + size, complex_dtype, order='F') out[:l_to_lm(self.lmin), ...] = 0 out[l_to_lm(self.lmin):, ...] = self alm_matrix = np.empty((1, self.lmax + 1, self.lmax + 1), complex_dtype, order='F') for mapidx in np.ndindex(*size): idx = (slice(None),) + mapidx mapdatautils.alm_complexpacked2complexmatrix(out[idx], alm_matrix[0,:,:]) rotate_alm_d(self.lmax, alm_matrix, psi, theta, phi) mapdatautils.alm_complexmatrix2complexpacked(alm_matrix[0,:,:], out[idx]) out = out[l_to_lm(self.lmin):, ...] return _HarmonicSphereMap(out, self.lmin, self.lmax, COMPLEX_BRIEF)
def to_harmonic(self, lmin, lmax, use_weights=True, weights_transform=None): """ :: >>> inpix = pixel_sphere_map(0, 4) >>> inpix.to_harmonic(0, 8) Brief complex harmonic sphere map with l=0..8 (45 coefficients) Convert a uniform map. First elements should be 12*sqrt(4 pi), the remaining elements 0:: >>> N = pixel_sphere_map(Nside=8, data=12) >>> x = N.to_harmonic(0, 16) >>> np.allclose(x[0], 12 * np.sqrt(4*np.pi)) True >>> np.allclose(x[1:], 0, atol=1e-1) True One can convert multiple maps at once: >>> N = np.hstack((N[:,None], N[:,None], N[:,None], N[:,None])) >>> N = np.dstack((N, N)) >>> N = pixel_sphere_map(data=N, Nside=8); N (4, 2)-stack of pixel sphere maps (ring-ordered, Nside=8, Npix=768) >>> x = N.to_harmonic(0, 16); x (4, 2)-stack of brief complex harmonic sphere maps with l=0..16 (153 coefficients) >>> np.allclose(x[0,:,:], 12 * np.sqrt(4*np.pi)) True >>> np.allclose(x[1:,:,:], 0, atol=.1) True """ if self.pixel_order == 'nested': return self.to_ring().to_harmonic(lmin, lmax) assert self.pixel_order == 'ring' self._check_not_pretending() dtype = to_complex_dtype(self.dtype) # for now, only double... assert dtype == np.complex128 size = self.shape[1:] numalm = l_to_lm(lmax + 1) alm_matrix_buf = np.empty((lmax + 1, lmax + 1), complex_dtype, order='F') alm = np.empty((numalm,) + size, complex_dtype, order='F') if use_weights: weight_ring_temperature = healpix_res.weight_ring(Nside=self.Nside)[0,:] if weights_transform is not None: weight_ring_temperature = weights_transform(weight_ring_temperature) else: weight_ring_temperature = np.ones(2 * self.Nside) for mapidx in np.ndindex(*size): idx = (slice(None),) + mapidx map = self[idx] mapdatautils.map2alm(lmax, map, weight_ring_temperature, out=alm_matrix_buf) mapdatautils.alm_complexmatrix2complexpacked(alm_matrix_buf, out=alm[idx]) # Trim away portion up to lmin alm = alm[l_to_lm(lmin):,...] return _HarmonicSphereMap(alm, lmin, lmax, COMPLEX_BRIEF)