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 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 load_h5py(cls, f, prepend=None): """Load object contents from an opened HDF5 file object.""" sc = cls() prefix = 'Config/' if prepend is not None: prefix = prepend + prefix sc.wavelength = float(f[prefix + 'wavelength'].value[0]) sc.aperture_radius = float(f[prefix + 'aperture_radius'].value[0]) sc.focal_length = float(f[prefix + 'focal_length'].value[0]) sc.image_width = int(f[prefix + 'image_width'].value[0]) sc.image_height = int(f[prefix + 'image_height'].value[0]) sc.pixel_size = float(f[prefix + 'pixel_size'].value[0]) sc.n_alpha = int(f[prefix + 'n_alpha'].value[0]) sc.n_beta = int(f[prefix + 'n_beta'].value[0]) sc.fit_L = int(f[prefix + 'fit_L'].value[0]) sc.fit_K = int(f[prefix + 'fit_K'].value[0]) sc.focus_positions = f[prefix + 'focus_positions'].value sc.xspace = f[prefix + 'xspace'].value sc.yspace = f[prefix + 'yspace'].value sc.phase_fit = FitZern.load_h5py(f, prepend=prefix + 'phase_fit/') sc.phase_grid = sc.phase_fit.z sc.cpsf = CPsf.load_h5py(f, prepend=prefix + 'cpsf/') sc.gpf_fit = FitZern.load_h5py(f, prepend=prefix + 'gpf_fit/') sc.gpf_fit.z = sc.cpsf.czern print('phase: n_alpha = {}, N_alpha = {}'.format( sc.n_alpha, sc.phase_grid.nk)) print('cpsf: n_beta = {}, N_beta = {}, N_f = {}'.format( sc.n_beta, sc.cpsf.czern.nk, sc.focus_positions.size)) return sc
def load_h5py(cls, f, prepend=None): """Load object contents from an opened HDF5 file object.""" sc = cls() prefix = 'Config/' if prepend is not None: prefix = prepend + prefix sc.wavelength = float(f[prefix + 'wavelength'].value[0]) sc.aperture_radius = float(f[prefix + 'aperture_radius'].value[0]) sc.focal_length = float(f[prefix + 'focal_length'].value[0]) sc.image_width = int(f[prefix + 'image_width'].value[0]) sc.image_height = int(f[prefix + 'image_height'].value[0]) sc.pixel_size = float(f[prefix + 'pixel_size'].value[0]) sc.n_alpha = int(f[prefix + 'n_alpha'].value[0]) sc.n_beta = int(f[prefix + 'n_beta'].value[0]) sc.fit_L = int(f[prefix + 'fit_L'].value[0]) sc.fit_K = int(f[prefix + 'fit_K'].value[0]) sc.focus_positions = f[prefix + 'focus_positions'].value sc.xspace = f[prefix + 'xspace'].value sc.yspace = f[prefix + 'yspace'].value sc.phase_fit = FitZern.load_h5py(f, prepend=prefix+'phase_fit/') sc.phase_grid = sc.phase_fit.z sc.cpsf = CPsf.load_h5py(f, prepend=prefix+'cpsf/') sc.gpf_fit = FitZern.load_h5py(f, prepend=prefix+'gpf_fit/') sc.gpf_fit.z = sc.cpsf.czern print('phase: n_alpha = {}, N_alpha = {}'.format( sc.n_alpha, sc.phase_grid.nk)) print('cpsf: n_beta = {}, N_beta = {}, N_f = {}'.format( sc.n_beta, sc.cpsf.czern.nk, sc.focus_positions.size)) return sc
def test_normalisations_complex(self): log = logging.getLogger('TestZern.test_normalisations_complex') n_beta = 6 L, K = 400, 393 # polar grid pol = CZern(n_beta) fitBeta = FitZern(pol, L, K) t1 = time() pol.make_pol_grid(fitBeta.rho_j, fitBeta.theta_i) t2 = time() log.debug('make pol grid {:.6f}'.format(t2 - t1)) # cartesian grid cart = CZern(n_beta) 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_beta, 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].conj())) 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, 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()
class Config: def __init__(self): pass 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)) def save(self, filename, prepend=None, libver='latest'): """Save object into an HDF5 file.""" f = h5py.File(filename, 'w', libver=libver) self.save_h5py(f, prepend=prepend) f.close() print('saved <{}>'.format(filename)) def save_h5py(self, f, prepend=None): """Dump object contents into an opened HDF5 file object.""" prefix = 'Config/' if prepend is not None: prefix = prepend + prefix params = { 'chunks': True, 'shuffle': True, 'fletcher32': True, 'compression': 'gzip', 'compression_opts': 9, } f.create_dataset( prefix + 'wavelength', data=np.array([self.wavelength], dtype=np.float)) f.create_dataset( prefix + 'aperture_radius', data=np.array([self.aperture_radius], dtype=np.float)) f.create_dataset( prefix + 'focal_length', data=np.array([self.focal_length], dtype=np.float)) f.create_dataset( prefix + 'image_width', data=np.array([self.image_width], dtype=np.int)) f.create_dataset( prefix + 'image_height', data=np.array([self.image_height], dtype=np.int)) f.create_dataset( prefix + 'pixel_size', data=np.array([self.pixel_size], dtype=np.float)) f.create_dataset( prefix + 'n_alpha', data=np.array([self.n_alpha], dtype=np.int)) f.create_dataset( prefix + 'n_beta', data=np.array([self.n_beta], dtype=np.int)) f.create_dataset( prefix + 'fit_L', data=np.array([self.fit_L], dtype=np.int)) f.create_dataset( prefix + 'fit_K', data=np.array([self.fit_K], dtype=np.int)) params['data'] = self.focus_positions f.create_dataset(prefix + 'focus_positions', **params) params['data'] = self.xspace f.create_dataset(prefix + 'xspace', **params) params['data'] = self.yspace f.create_dataset(prefix + 'yspace', **params) self.phase_fit.save_h5py(f, prepend=prefix+'phase_fit/') self.cpsf.save_h5py(f, prepend=prefix+'cpsf/') self.gpf_fit.save_h5py(f, prepend=prefix+'gpf_fit/') @classmethod def load(cls, filename, prepend=None): """Load object from an HDF5 file.""" f = h5py.File(filename, 'r') print('load <{}>'.format(filename)) z = cls.load_h5py(f, prepend=prepend) f.close() return z @classmethod def load_h5py(cls, f, prepend=None): """Load object contents from an opened HDF5 file object.""" sc = cls() prefix = 'Config/' if prepend is not None: prefix = prepend + prefix sc.wavelength = float(f[prefix + 'wavelength'].value[0]) sc.aperture_radius = float(f[prefix + 'aperture_radius'].value[0]) sc.focal_length = float(f[prefix + 'focal_length'].value[0]) sc.image_width = int(f[prefix + 'image_width'].value[0]) sc.image_height = int(f[prefix + 'image_height'].value[0]) sc.pixel_size = float(f[prefix + 'pixel_size'].value[0]) sc.n_alpha = int(f[prefix + 'n_alpha'].value[0]) sc.n_beta = int(f[prefix + 'n_beta'].value[0]) sc.fit_L = int(f[prefix + 'fit_L'].value[0]) sc.fit_K = int(f[prefix + 'fit_K'].value[0]) sc.focus_positions = f[prefix + 'focus_positions'].value sc.xspace = f[prefix + 'xspace'].value sc.yspace = f[prefix + 'yspace'].value sc.phase_fit = FitZern.load_h5py(f, prepend=prefix+'phase_fit/') sc.phase_grid = sc.phase_fit.z sc.cpsf = CPsf.load_h5py(f, prepend=prefix+'cpsf/') sc.gpf_fit = FitZern.load_h5py(f, prepend=prefix+'gpf_fit/') sc.gpf_fit.z = sc.cpsf.czern print('phase: n_alpha = {}, N_alpha = {}'.format( sc.n_alpha, sc.phase_grid.nk)) print('cpsf: n_beta = {}, N_beta = {}, N_f = {}'.format( sc.n_beta, sc.cpsf.czern.nk, sc.focus_positions.size)) return sc
'--rms', type=float, default=1.0, help='Rms of the alpha aberration.') parser.add_argument( '--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))
.. [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__': # grid sizes L, K = 95, 105 # complex-valued Zernike polynomials up to the 4-th radial order gpf_pol = CZern(4) # to approximate the GPF # FitZern computes the approximate inner products, see Eq. (B4) in [A2015] ip = FitZern(gpf_pol, L, K) gpf_pol.make_pol_grid(ip.rho_j, ip.theta_i) # make a polar grid # random vector of Zernike coefficients to be estimated beta_true = normal(size=gpf_pol.nk) + 1j * normal(size=gpf_pol.nk) # random generalised pupil function P P = gpf_pol.eval_grid(beta_true) # estimate the random vector from the GPF grid beta_hat = ip.fit(P) # plot the results p.figure(2) # real part of the Zernike coefficients of beta_true and beta_hat
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))
def do_test(cls, complex_a): z = cls(4) F = FitZern(z, self.L, self.K) theta_i = F.theta_i rho_j = F.rho_j z.make_pol_grid(rho_j, theta_i) if complex_a: c = normal(size=z.nk) + 1j*normal(size=z.nk) else: c = normal(size=z.nk) PhiN = np.array( [z.eval_a(c, rh, th) for rh in rho_j for th in theta_i], order='F') ce1 = F.fit(PhiN) # create tmp path tmpfile = NamedTemporaryFile() tmppath = tmpfile.name tmpfile.close() F.save(tmppath) F2 = FitZern.load(tmppath) PhiN1 = np.array( [F.z.eval_a(c, rh, th) for rh in rho_j for th in theta_i], order='F') PhiN2 = np.array( [F2.z.eval_a(c, rh, th) for rh in rho_j for th in theta_i], order='F') self.assertTrue(isinstance(F, FitZern)) self.assertTrue(isinstance(F2, FitZern)) if complex_a: self.assertTrue(isinstance(F.z, CZern)) self.assertTrue(isinstance(F2.z, CZern)) else: self.assertTrue(isinstance(F.z, RZern)) self.assertTrue(isinstance(F2.z, RZern)) self.assertTrue(norm(PhiN - PhiN1) == 0) self.assertTrue(norm(PhiN - PhiN2) == 0) self.assertTrue(norm(F.z.coefnorm - F2.z.coefnorm) == 0) self.assertTrue(norm(F.z.ntab - F2.z.ntab) == 0) self.assertTrue(norm(F.z.mtab - F2.z.mtab) == 0) self.assertTrue(F.z.n == F2.z.n) self.assertTrue(F.z.nk == F2.z.nk) self.assertTrue(F.z.normalise == F2.z.normalise) self.assertTrue(norm(F.z.rhoitab - F2.z.rhoitab) == 0) self.assertTrue(norm(F.z.rhotab - F2.z.rhotab) == 0) self.assertTrue(F.z.numpy_dtype == F2.z.numpy_dtype) self.assertTrue(norm(F.z.ZZ - F2.z.ZZ) == 0) self.assertTrue(norm(F.A - F2.A) == 0) self.assertTrue(norm(F.I_cosm - F2.I_cosm) == 0) self.assertTrue(norm(F.I_sinm - F2.I_sinm) == 0) self.assertTrue(norm(F.I_Rnmrho - F2.I_Rnmrho) == 0) self.assertTrue(F.K == F2.K) self.assertTrue(F.L == F2.L) self.assertTrue(norm(F.rho_a - F2.rho_a) == 0) self.assertTrue(norm(F.rho_b - F2.rho_b) == 0) self.assertTrue(norm(F.rho_j - F2.rho_j) == 0) self.assertTrue(norm(F.theta_a - F2.theta_a) == 0) self.assertTrue(norm(F.theta_b - F2.theta_b) == 0) self.assertTrue(norm(F.theta_i - F2.theta_i) == 0) ce2 = F2.fit(PhiN) self.assertTrue(norm(ce2 - ce1) < self.max_enorm) os.unlink(tmppath) del z, F, F2, c, ce1, ce2, PhiN, PhiN1, PhiN2
class Config: def __init__(self): pass 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)) def save(self, filename, prepend=None, libver='latest'): """Save object into an HDF5 file.""" f = h5py.File(filename, 'w', libver=libver) self.save_h5py(f, prepend=prepend) f.close() print('saved <{}>'.format(filename)) def save_h5py(self, f, prepend=None): """Dump object contents into an opened HDF5 file object.""" prefix = 'Config/' if prepend is not None: prefix = prepend + prefix params = { 'chunks': True, 'shuffle': True, 'fletcher32': True, 'compression': 'gzip', 'compression_opts': 9, } f.create_dataset(prefix + 'wavelength', data=np.array([self.wavelength], dtype=np.float)) f.create_dataset(prefix + 'aperture_radius', data=np.array([self.aperture_radius], dtype=np.float)) f.create_dataset(prefix + 'focal_length', data=np.array([self.focal_length], dtype=np.float)) f.create_dataset(prefix + 'image_width', data=np.array([self.image_width], dtype=np.int)) f.create_dataset(prefix + 'image_height', data=np.array([self.image_height], dtype=np.int)) f.create_dataset(prefix + 'pixel_size', data=np.array([self.pixel_size], dtype=np.float)) f.create_dataset(prefix + 'n_alpha', data=np.array([self.n_alpha], dtype=np.int)) f.create_dataset(prefix + 'n_beta', data=np.array([self.n_beta], dtype=np.int)) f.create_dataset(prefix + 'fit_L', data=np.array([self.fit_L], dtype=np.int)) f.create_dataset(prefix + 'fit_K', data=np.array([self.fit_K], dtype=np.int)) params['data'] = self.focus_positions f.create_dataset(prefix + 'focus_positions', **params) params['data'] = self.xspace f.create_dataset(prefix + 'xspace', **params) params['data'] = self.yspace f.create_dataset(prefix + 'yspace', **params) self.phase_fit.save_h5py(f, prepend=prefix + 'phase_fit/') self.cpsf.save_h5py(f, prepend=prefix + 'cpsf/') self.gpf_fit.save_h5py(f, prepend=prefix + 'gpf_fit/') @classmethod def load(cls, filename, prepend=None): """Load object from an HDF5 file.""" f = h5py.File(filename, 'r') print('load <{}>'.format(filename)) z = cls.load_h5py(f, prepend=prepend) f.close() return z @classmethod def load_h5py(cls, f, prepend=None): """Load object contents from an opened HDF5 file object.""" sc = cls() prefix = 'Config/' if prepend is not None: prefix = prepend + prefix sc.wavelength = float(f[prefix + 'wavelength'].value[0]) sc.aperture_radius = float(f[prefix + 'aperture_radius'].value[0]) sc.focal_length = float(f[prefix + 'focal_length'].value[0]) sc.image_width = int(f[prefix + 'image_width'].value[0]) sc.image_height = int(f[prefix + 'image_height'].value[0]) sc.pixel_size = float(f[prefix + 'pixel_size'].value[0]) sc.n_alpha = int(f[prefix + 'n_alpha'].value[0]) sc.n_beta = int(f[prefix + 'n_beta'].value[0]) sc.fit_L = int(f[prefix + 'fit_L'].value[0]) sc.fit_K = int(f[prefix + 'fit_K'].value[0]) sc.focus_positions = f[prefix + 'focus_positions'].value sc.xspace = f[prefix + 'xspace'].value sc.yspace = f[prefix + 'yspace'].value sc.phase_fit = FitZern.load_h5py(f, prepend=prefix + 'phase_fit/') sc.phase_grid = sc.phase_fit.z sc.cpsf = CPsf.load_h5py(f, prepend=prefix + 'cpsf/') sc.gpf_fit = FitZern.load_h5py(f, prepend=prefix + 'gpf_fit/') sc.gpf_fit.z = sc.cpsf.czern print('phase: n_alpha = {}, N_alpha = {}'.format( sc.n_alpha, sc.phase_grid.nk)) print('cpsf: n_beta = {}, N_beta = {}, N_f = {}'.format( sc.n_beta, sc.cpsf.czern.nk, sc.focus_positions.size)) return sc
""" 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 p.figure(2) # Zernike coefficients of alpha_true and alpha_hat
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))
def do_test(cls, complex_a): z = cls(4) F = FitZern(z, self.L, self.K) theta_i = F.theta_i rho_j = F.rho_j z.make_pol_grid(rho_j, theta_i) if complex_a: c = normal(size=z.nk) + 1j * normal(size=z.nk) else: c = normal(size=z.nk) PhiN = np.array( [z.eval_a(c, rh, th) for rh in rho_j for th in theta_i], order='F') ce1 = F.fit(PhiN) # create tmp path tmpfile = NamedTemporaryFile() tmppath = tmpfile.name tmpfile.close() F.save(tmppath) F2 = FitZern.load(tmppath) PhiN1 = np.array( [F.z.eval_a(c, rh, th) for rh in rho_j for th in theta_i], order='F') PhiN2 = np.array( [F2.z.eval_a(c, rh, th) for rh in rho_j for th in theta_i], order='F') self.assertTrue(isinstance(F, FitZern)) self.assertTrue(isinstance(F2, FitZern)) if complex_a: self.assertTrue(isinstance(F.z, CZern)) self.assertTrue(isinstance(F2.z, CZern)) else: self.assertTrue(isinstance(F.z, RZern)) self.assertTrue(isinstance(F2.z, RZern)) self.assertTrue(norm(PhiN - PhiN1) == 0) self.assertTrue(norm(PhiN - PhiN2) == 0) self.assertTrue(norm(F.z.coefnorm - F2.z.coefnorm) == 0) self.assertTrue(norm(F.z.ntab - F2.z.ntab) == 0) self.assertTrue(norm(F.z.mtab - F2.z.mtab) == 0) self.assertTrue(F.z.n == F2.z.n) self.assertTrue(F.z.nk == F2.z.nk) self.assertTrue(F.z.normalise == F2.z.normalise) self.assertTrue(norm(F.z.rhoitab - F2.z.rhoitab) == 0) self.assertTrue(norm(F.z.rhotab - F2.z.rhotab) == 0) self.assertTrue(F.z.numpy_dtype == F2.z.numpy_dtype) self.assertTrue(norm(F.z.ZZ - F2.z.ZZ) == 0) self.assertTrue(norm(F.A - F2.A) == 0) self.assertTrue(norm(F.I_cosm - F2.I_cosm) == 0) self.assertTrue(norm(F.I_sinm - F2.I_sinm) == 0) self.assertTrue(norm(F.I_Rnmrho - F2.I_Rnmrho) == 0) self.assertTrue(F.K == F2.K) self.assertTrue(F.L == F2.L) self.assertTrue(norm(F.rho_a - F2.rho_a) == 0) self.assertTrue(norm(F.rho_b - F2.rho_b) == 0) self.assertTrue(norm(F.rho_j - F2.rho_j) == 0) self.assertTrue(norm(F.theta_a - F2.theta_a) == 0) self.assertTrue(norm(F.theta_b - F2.theta_b) == 0) self.assertTrue(norm(F.theta_i - F2.theta_i) == 0) ce2 = F2.fit(PhiN) self.assertTrue(norm(ce2 - ce1) < self.max_enorm) os.unlink(tmppath) del z, F, F2, c, ce1, ce2, PhiN, PhiN1, PhiN2