def get_kappa(self): """ kappa map. kappa is -1/2 del phi :return: """ dfxdx = PDP(self.get_dx(), axis=1, h=self.rmin[1], rule=self.rule) dfydy = PDP(self.get_dy(), axis=0, h=self.rmin[0], rule=self.rule) return -0.5 * (dfxdx + dfydy)
def get_omega(self): """ curl kappa map :return: """ dfxdy = PDP(self.get_dx(), axis=0, h=self.rmin[0], rule=self.rule) dfydx = PDP(self.get_dy(), axis=1, h=self.rmin[1], rule=self.rule) return 0.5 * (dfxdy - dfydx)
def get_dnorm_Omega(self): """ Norm of the displacement due to curl :return: """ Omega = self.get_Omega() return np.sqrt(PDP(Omega, 1, h=self.rmin[1]) ** 2 + PDP(Omega, 0, h=self.rmin[0]) ** 2)
def get_dnorm_phi(self): """ Norm of the displacement due to phi :return: """ phi = self.get_phi() return np.sqrt(PDP(phi, 1, h=self.rmin[1]) ** 2 + PDP(phi, 0, h=self.rmin[0]) ** 2)
def get_det_magn_chk_N(self, N, extra_buff=np.array((5, 5))): """ Returns chunk N of magnification map, adding an extra buffer 'extra_buff' to avoid surprises with the periodic derivatives. """ dx, dy = self.get_dxdy_chk_N(N, buffers=self.buffers + extra_buff) # In physical units det = (PDP(dx, axis=1, h=self.rmin[1], rule=self.rule) + 1.) \ * (PDP(dy, axis=0, h=self.rmin[0], rule=self.rule) + 1.) det -= PDP(dy, axis=1, h=self.rmin[1], rule=self.rule) * \ PDP(dx, axis=0, h=self.rmin[0], rule=self.rule) return det[extra_buff[0]:dx.shape[0] - extra_buff[0], extra_buff[1]:dx.shape[1] - extra_buff[1]]
def get_det_magn(self): """ Returns entire magnification det map. """ # FIXME : bad if not self.cache_magn: det = (PDP(self.get_dx(), axis=1, h=self.rmin[1], rule=self.rule) + 1.) \ * (PDP(self.get_dy(), axis=0, h=self.rmin[0], rule=self.rule) + 1.) det -= PDP(self.get_dy(), axis=1, h=self.rmin[1], rule=self.rule) * \ PDP(self.get_dx(), axis=0, h=self.rmin[0], rule=self.rule) return det else: assert self.has_lib_dir(), 'Specify lib_dir if you want to cache magn' fname = self.lib_dir + '/det_magn_%s_%s_rank%s.npy' % \ (hashlib.sha1(self.get_dx()[0, 0:100]).hexdigest(), hashlib.sha1(self.get_dy()[0, 0:100]).hexdigest(), pbs.rank) if not os.path.exists(fname): # and pbs.rank == 0: det = (PDP(self.get_dx(), axis=1, h=self.rmin[1], rule=self.rule) + 1.) \ * (PDP(self.get_dy(), axis=0, h=self.rmin[0], rule=self.rule) + 1.) det -= PDP(self.get_dy(), axis=1, h=self.rmin[1], rule=self.rule) * \ PDP(self.get_dx(), axis=0, h=self.rmin[0], rule=self.rule) print " ffs_displacement caching ", fname np.save(fname, det) del det # pbs.barrier() return np.load(fname)
def calc_ffinv(self, iter, key): """ Calculate displacement at iter and its inverse. Only pbs rank 0 can do this. :param iter: :param key: :return: """ assert self.PBSRANK == 0, 'SINGLE MPI METHOD' if iter < 0: return assert key.lower() in ['p', 'o'], key # potential or curl potential. fname_dx, fname_dy = self.getfnames_f(key, iter) if not os.path.exists(fname_dx) or not os.path.exists(fname_dy): # FIXME : does this from plm assert self.is_previous_iter_done(iter, key) Phi_est_WF = self.get_Phimap(iter, key) assert self.cov.lib_skyalm.shape == Phi_est_WF.shape assert self.cov.lib_skyalm.shape == self.lib_qlm.shape assert self.cov.lib_skyalm.lsides == self.lib_qlm.lsides rmin = np.array(self.cov.lib_skyalm.lsides) / np.array( self.cov.lib_skyalm.shape) print 'rank %s caching displacement comp. for it. %s for key %s' % ( self.PBSRANK, iter, key) if key.lower() == 'p': dx = PDP(Phi_est_WF, axis=1, h=rmin[1]) dy = PDP(Phi_est_WF, axis=0, h=rmin[0]) else: dx = -PDP(Phi_est_WF, axis=0, h=rmin[0]) dy = PDP(Phi_est_WF, axis=1, h=rmin[1]) if self.PBSRANK == 0: np.save(fname_dx, dx) np.save(fname_dy, dy) del dx, dy lib_dir = self.lib_dir + '/f_%04d_libdir' % iter if not os.path.exists(lib_dir): os.makedirs(lib_dir) fname_invdx, fname_invdy = self.getfnames_finv(key, iter) if not os.path.exists(fname_invdx) or not os.path.exists(fname_invdy): f = self.load_f(iter, key) print 'rank %s inverting displacement it. %s for key %s' % ( self.PBSRANK, iter, key) f_inv = f.get_inverse(use_Pool=self.use_Pool_inverse) np.save(fname_invdx, f_inv.get_dx()) np.save(fname_invdy, f_inv.get_dy()) lib_dir = self.lib_dir + '/finv_%04d_libdir' % iter if not os.path.exists(lib_dir): os.makedirs(lib_dir) assert os.path.exists(fname_invdx), fname_invdx assert os.path.exists(fname_invdy), fname_invdy return
def get_magn_mat_chk_N(self, N, extra_buff=np.array((5, 5))): """ Returns chk number 'N' of magnification matrix, adding an extra-buffer to avoid surprises with periodic derivatives. """ # Setting up dx and dy displacement chunks : # We add small extra buffer to get correct derivatives in the chunks dx, dy = self.get_dxdy_chk_N(N, buffers=self.buffers + extra_buff) # In physical units # Jacobian matrix : sl0 = slice(extra_buff[0], dx.shape[0] - extra_buff[0]) sl1 = slice(extra_buff[1], dx.shape[1] - extra_buff[1]) dfxdx = PDP(dx, axis=1, h=self.rmin[1], rule=self.rule)[sl0, sl1] dfydx = PDP(dy, axis=1, h=self.rmin[1], rule=self.rule)[sl0, sl1] dfxdy = PDP(dx, axis=0, h=self.rmin[0], rule=self.rule)[sl0, sl1] dfydy = PDP(dy, axis=0, h=self.rmin[0], rule=self.rule)[sl0, sl1] return {'kappa': 0.5 * (dfxdx + dfydy), 'omega': 0.5 * (dfxdy - dfydx), \ 'gamma_U': 0.5 * (dfxdy + dfydx), 'gamma_Q': 0.5 * (dfxdx - dfydy), \ 'det': (dfxdx + 1.) * (dfydy + 1.) - dfydx * dfxdy}
def lens_map_crude(self, map, crude): """ Crudest lens operation, just rounding to nearest pixel. :param map: :return: """ if crude == 1: # Plain interpolation to nearest pixel ly, lx = np.indices(self.shape) lx = np.int32(np.round((lx + self.get_dx_ingridunits()).flatten())) % self.shape[1] # Periodicity ly = np.int32(np.round((ly + self.get_dy_ingridunits())).flatten()) % self.shape[0] # Periodicity return self.load_map(map).flatten()[FlatIndices(np.array([ly, lx]), self.shape)].reshape(self.shape) elif crude == 2: # First order series expansion return self.load_map(map) \ + PDP(self.load_map(map), axis=0, h=self.rmin[0], rule=self.rule) * self.get_dy() \ + PDP(self.load_map(map), axis=1, h=self.rmin[1], rule=self.rule) * self.get_dx() else: assert 0, crude
def get_inverse_chk_N(self, N, NR_iter=None): """ Returns inverse displacement in chunk N Uses periodic boundary conditions, which is not applicable to chunks, thus there will be boudary effects on the edges (2 or 4 pixels depending on the rule). Make sure the buffer is large enough. """ if NR_iter is None: NR_iter = self.NR_iter # Inverse magn. elements. (with a minus sign) We may need to spline these later for further NR iterations : extra_buff = np.array((5, 5)) * ( np.array(self.chk_shape) != np.array(self.shape)) # To avoid surprises with the periodic derivatives dx = np.zeros(self.chk_shape + 2 * extra_buff) # will dx displ. in grid units of each chunk (typ. (256 * 256) ) dy = np.zeros(self.chk_shape + 2 * extra_buff) # will dy displ. in grid units of each chunk (typ. (256 * 256) ) sLDs, sHDs = map_spliter.periodicmap_spliter().get_slices_chk_N(N, self.LD_res, self.HD_res, (self.buffers[0] + extra_buff[0], self.buffers[1] + extra_buff[1])) rmin0 = self.lsides[0] / self.shape[0] rmin1 = self.lsides[1] / self.shape[1] for sLD, sHD in zip(sLDs, sHDs): dx[sLD] = self.get_dx()[sHD] / rmin1 # Need grid units displacement for the bicubic spline dy[sLD] = self.get_dy()[sHD] / rmin0 # Jacobian matrix of the chunk : sl0 = slice(extra_buff[0], dx.shape[0] - extra_buff[0]) sl1 = slice(extra_buff[1], dx.shape[1] - extra_buff[1]) Minv_yy = - (PDP(dx, axis=1)[sl0, sl1] + 1.) Minv_xx = - (PDP(dy, axis=0)[sl0, sl1] + 1.) Minv_xy = PDP(dy, axis=1)[sl0, sl1] Minv_yx = PDP(dx, axis=0)[sl0, sl1] dx = dx[sl0, sl1] dy = dy[sl0, sl1] det = Minv_yy * Minv_xx - Minv_xy * Minv_yx if not np.all(det > 0.): print "ffs_displ::Negative value in det k : something's weird, you'd better check that" # Inverse magn. elements. (with a minus sign) We may need to spline these later for further NR iterations : Minv_xx /= det Minv_yy /= det Minv_xy /= det Minv_yx /= det del det ex = (Minv_xx * dx + Minv_xy * dy) ey = (Minv_yx * dx + Minv_yy * dy) if NR_iter == 0: return ex * rmin1, ey * rmin0 # Setting up a bunch of splines to interpolate the increment to the displacement according to Newton-Raphson. # Needed are splines of the forward displacement and of the (inverse, as implemented here) magnification matrix. # Hopefully the map resolution is enough to spline the magnification matrix. s0, s1 = self.chk_shape r0 = s0 r1 = s1 / 2 + 1 # rfft shape w0 = 6. / (2. * np.cos(2. * np.pi * Freq(np.arange(r0), s0) / s0) + 4.) w1 = 6. / (2. * np.cos(2. * np.pi * Freq(np.arange(r1), s1) / s1) + 4.) # FIXME: switch to pyfftw : bic_filter = lambda _map: np.fft.irfft2(np.fft.rfft2(_map) * np.outer(w0, w1)) dx = bic_filter(dx) dy = bic_filter(dy) Minv_xy = bic_filter(Minv_xy) Minv_yx = bic_filter(Minv_yx) Minv_xx = bic_filter(Minv_xx) Minv_yy = bic_filter(Minv_yy) header = r' "%s/lensit/gpu/bicubicspline.h" ' % li.LENSITDIR iterate = r"\ double fx,fy;\ double ex_len_dx,ey_len_dy,len_Mxx,len_Mxy,len_Myx,len_Myy;\ int i = 0;\ for(int y= 0; y < width; y++ )\ {\ for(int x = 0; x < width; x++,i++)\ {\ fx = x + ex[i];\ fy = y + ey[i];\ ex_len_dx = ex[i] + bicubiclensKernel(dx,fx,fy,width);\ ey_len_dy = ey[i] + bicubiclensKernel(dy,fx,fy,width);\ len_Mxx = bicubiclensKernel(Minv_xx,fx,fy,width);\ len_Myy = bicubiclensKernel(Minv_yy,fx,fy,width);\ len_Mxy = bicubiclensKernel(Minv_xy,fx,fy,width);\ len_Myx = bicubiclensKernel(Minv_yx,fx,fy,width);\ ex[i] += len_Mxx * ex_len_dx + len_Mxy * ey_len_dy;\ ey[i] += len_Myx * ex_len_dx + len_Myy * ey_len_dy;\ }\ }\ " width = int(s0) assert s0 == s1, 'Havent checked how this works with rectangular maps' for i in range(0, NR_iter): weave.inline(iterate, ['ex', 'ey', 'dx', 'dy', 'Minv_xx', 'Minv_yy', 'Minv_xy', 'Minv_yx', 'width'], headers=[header]) return ex * rmin1, ey * rmin0