def test_normalisations_real(self): log = logging.getLogger('TestZern.test_normalisations_real') n_alpha = 6 L, K = 400, 357 # polar grid pol = RZern(n_alpha) fitAlpha = FitZern(pol, L, K) t1 = time() pol.make_pol_grid(fitAlpha.rho_j, fitAlpha.theta_i) t2 = time() log.debug('make pol grid {:.6f}'.format(t2 - t1)) # cartesian grid cart = RZern(n_alpha) dd = np.linspace(-1.0, 1.0, max(L, K)) xx, yy = np.meshgrid(dd, dd) t1 = time() cart.make_cart_grid(xx, yy) t2 = time() log.debug('make cart grid {:.6f}'.format(t2 - t1)) smap = np.isfinite(cart.eval_grid(np.zeros(cart.nk))) scale = (1.0 / np.sum(smap)) log.debug('') log.debug('{} modes, {} x {} grid'.format(n_alpha, L, K)) for i in range(pol.nk): a = np.zeros(pol.nk) a[i] = 1.0 Phi_a = cart.eval_grid(a) for j in range(pol.nk): b = np.zeros(pol.nk) b[j] = 1.0 Phi_b = cart.eval_grid(b) ip = scale * np.sum(Phi_a[smap] * Phi_b[smap]) if i == j: eip = 1.0 else: eip = 0.0 iperr = abs(ip - eip) log.debug('<{:02},{:02}> = {:+e} {:+e}'.format( i + 1, j + 1, ip, iperr)) self.assertTrue(iperr < self.max_ip_err)
def __init__(self, n=6, L=200, K=250): # real-valued Zernike polynomials up to the n-th radial order rzern = RZern(n) # make a cartesian grid (unit disk pupil coordinates) ddx = np.linspace(-1.0, 1.0, K) ddy = np.linspace(-1.0, 1.0, L) xv, yv = np.meshgrid(ddx, ddy) rzern.make_cart_grid(xv, yv) self.rzern = rzern self.grid_size = (L, K)
def __init__(self, unparsed): super().__init__() args = self.do_cmdline(unparsed) # plot objects phaseplot = PhasePlot(n=args.n_alpha) # to plot beta and the PSF betaplot = BetaPlot(args) # to plot the phase # complex-valued Zernike polynomials for the GPF ip = FitZern(CZern(args.n_beta), args.fit_L, args.fit_K) # real-valued Zernike polynomials for the phase phase_pol = RZern(args.n_alpha) phase_pol.make_pol_grid(ip.rho_j, ip.theta_i) # make a polar grid # real-valued Zernike coefficients alpha = np.zeros(phase_pol.nk) # set the alpha coefficients randomly if args.random: alpha1 = normal(size=alpha.size - 1) alpha1 = (args.rms / norm(alpha1)) * alpha1 alpha[1:] = alpha1 del alpha1 self.rms = args.rms self.alpha = alpha self.phase_pol = phase_pol self.ip = ip self.betaplot = betaplot self.phaseplot = phaseplot # fit beta coefficients from alpha coefficients self.alpha2beta() # make gui self.make_gui()
def test_fit_real_numpy(self): log = logging.getLogger('TestFitZern.test_fit_real_numpy') z = RZern(4) F = FitZern(z, self.L, self.K) theta_i = F.theta_i rho_j = F.rho_j c = normal(size=z.nk) Phi = [z.eval_a(c, rh, th) for rh in rho_j for th in theta_i] time1 = time() ce = F._fit_slow(Phi) time2 = time() log.debug('elapsed FIT_LIST {:.6f}'.format(time2 - time1)) time1 = time() ce2 = F.fit(np.array(Phi, order='F')) time2 = time() log.debug('elapsed FIT_NUMPY {:.6f}'.format(time2 - time1)) enorm = norm(ce2 - np.array(ce, order='F')) log.debug('enorm {:e}'.format(enorm)) self.assertTrue(enorm < self.max_enorm)
def test_fit_real(self): log = logging.getLogger('TestFitZern.test_fit_real') z = RZern(4) F = FitZern(z, self.L, self.K) theta_i = F.theta_i rho_j = F.rho_j c = normal(size=z.nk) time1 = time() Phi = [z.eval_a(c, rh, th) for rh in rho_j for th in theta_i] time2 = time() log.debug('eval Phi {:.4f}'.format(time2 - time1)) time1 = time() ce = F._fit_slow(Phi) time2 = time() log.debug('elapsed time {:.4f}'.format(time2 - time1)) err1 = norm(np.array(c) - np.array(ce)) max1 = max([abs(c[i] - ce[i]) for i in range(z.nk)]) log.debug('err1 {:e} max1 {:e}'.format(err1, max1)) self.assertTrue(err1 < self.max_fit_norm)
def setUp(self): self.pupil = RZern(4) self.max_enorm = 1e-9 self.max_ip_err = 5e-2
'--random', action='store_true', help='Make a random alpha aberration.') parser.add_argument( '--fit-L', type=int, default=95, metavar='L', help='Grid size for the inner products.') parser.add_argument( '--fit-K', type=int, default=105, metavar='K', help='Grid size for the inner products.') args = parser.parse_args() # complex-valued Zernike polynomials for the GPF ip = FitZern(CZern(args.n_beta), args.fit_L, args.fit_K) # real-valued Zernike polynomials for the phase phase_pol = RZern(args.n_alpha) phase_pol.make_pol_grid(ip.rho_j, ip.theta_i) # make a polar grid # real-valued Zernike coefficients alpha = np.zeros(phase_pol.nk) # nm to linear index conversion nmlist = list(zip(phase_pol.ntab, phase_pol.mtab)) # set an alpha coefficient using the (n, m) indeces if args.nm[0] != -1 and args.nm[0] != -1: try: k = nmlist.index(tuple(args.nm)) alpha[k] = args.rms except BaseException: print('Cannot find indeces ' + str(args.nm))
def make(self, wavelength, aperture_radius, focal_length, pixel_size, image_width, image_height, n_alpha, n_beta, fit_L, fit_K, focus_positions): self.wavelength = wavelength self.aperture_radius = aperture_radius self.focal_length = focal_length self.image_width = image_width self.image_height = image_height self.pixel_size = pixel_size self.n_alpha, self.n_beta = n_alpha, n_beta self.fit_L, self.fit_K = fit_L, fit_K self.focus_positions = np.array(focus_positions) fu = enz.get_field_unit(wavelength, aperture_radius, focal_length) def make_space(w, p, fu): if w % 2 == 0: return np.linspace(-(w / 2 - 0.5), w / 2 - 0.5, w) * p / fu else: return np.linspace(-(w - 1) / 2, (w - 1) / 2, w) * p / fu # image side space xspace = make_space(image_width, pixel_size, fu) yspace = make_space(image_height, pixel_size, fu) self.xspace, self.yspace = xspace, yspace # phase self.phase_grid = RZern(n_alpha) self.phase_fit = FitZern(self.phase_grid, self.fit_L, self.fit_K) print('phase: n_alpha = {}, N_alpha = {}'.format( self.n_alpha, self.phase_grid.nk)) # complex psf self.cpsf = CPsf(n_beta) self.gpf_fit = FitZern(self.cpsf.czern, self.fit_L, self.fit_K) print('cpsf: n_beta = {}, N_beta = {}, N_f = {}'.format( n_beta, self.cpsf.czern.nk, self.focus_positions.size)) # make phase polar grid t1 = time.time() self.phase_grid.make_pol_grid(self.phase_fit.rho_j, self.phase_fit.theta_i) t2 = time.time() print('make phase pol grid {:.6f}'.format(t2 - t1)) # make gpf polar grid (Zernike approximation) t1 = time.time() self.cpsf.czern.make_pol_grid(self.phase_fit.rho_j, self.phase_fit.theta_i) t2 = time.time() print('make gpf pol grid {:.6f}'.format(t2 - t1)) # make cpsf cart grid t1 = time.time() self.cpsf.make_cart_grid(x_sp=xspace, y_sp=yspace, f_sp=focus_positions) t2 = time.time() print('make cpsf cart grid {:.6f}'.format(t2 - t1))
.. [A2015] Jacopo Antonello and Michel Verhaegen, "Modal-based phase retrieval for adaptive optics," J. Opt. Soc. Am. A 32, 1160-1170 (2015) . `url <http://dx.doi.org/10.1364/JOSAA.32.001160>`__. """ if __name__ == '__main__': # plotting stuff phaseplot = PhasePlot() # grid sizes L, K = 95, 105 # real-valued Zernike polynomials up to the 6-th radial order phase_pol = RZern(6) # FitZern computes the approximate inner products, see Eq. (B2) in [A2015] ip = FitZern(phase_pol, L, K) phase_pol.make_pol_grid(ip.rho_j, ip.theta_i) # make a polar grid # random vector of Zernike coefficients to be estimated alpha_true = normal(size=phase_pol.nk) # phase grid Phi = phase_pol.eval_grid(alpha_true) # estimate the random vector from the phase grid alpha_hat = ip.fit(Phi) # plot the results