def __init__( self, wavelength=632.8e-9, # wavelength in [m] aperture_radius=0.002, # aperture radius in [m] focal_length=500e-3, # focal length in [m] pixel_size=7.4e-6, # pixel size in [m] image_width=75, # [pixels], odd to get the origin as well image_height=151, # [pixels] fspace=np.linspace( # defocus planes specified by an array of -3.0, 2.0, 6), # defocus parameters n_beta=4 # max radial order for the Zernikes ): # compute the diffraction unit (lambda/NA) fu = enz.get_field_unit( wavelength=wavelength, aperture_radius=aperture_radius, exit_pupil_sphere_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) # consider complex-valued Zernike polynomials up to the radial order # n_beta to approximate the PSF, see Eq. (1) and Eq. (2) in [A2015] cpsf = CPsf(n_beta) # make a cartesian grid to evaluate the PSF t1 = time() cpsf.make_cart_grid(x_sp=xspace, y_sp=yspace, f_sp=fspace) t2 = time() print('make_cart_grid {:.6f} sec'.format(t2 - t1)) self.xspace = xspace self.yspace = yspace self.fspace = fspace self.cpsf = cpsf self.image_size = (image_height, image_width)
def test_eval_U_grid1(self): log = logging.getLogger("TestCPsf.test_eval_U_grid1") enz = CPsf(8) r_sp = float(abs(normal(size=1))[0]) ph_sp = float(normal(size=1)[0]) f_sp = float(normal(size=1)[0]) enz.make_pol_grid([r_sp], [ph_sp], [f_sp]) beta = normal(size=enz.czern.nk) + 1j * normal(size=enz.czern.nk) a = enz.eval_grid(beta, 0, 0, 0) b = enz.U(beta, r_sp, ph_sp, f_sp) log.debug("r = {:e}, ph = {:e}, f = {:e}".format(r_sp, ph_sp, f_sp)) log.debug("a {:s} {}".format(str(type(a)), a)) log.debug("b {:s} {}".format(str(type(b)), b)) log.debug("{}".format(abs(a - b))) self.assertTrue(abs(a - b) < self.max_enorm)
def test_save(self): rho_j = np.array([ 0, 0.11111111111111, 0.22222222222222, 0.33333333333333, 0.44444444444444, 0.55555555555556, 0.66666666666667, 0.77777777777778, 0.88888888888889, 1 ]) theta_i = np.array([ 0, 0.69813170079773, 1.3962634015955, 2.0943951023932, 2.7925268031909, 3.4906585039887, 4.1887902047864, 4.8869219055841, 5.5850536063819, 6.2831853071796 ]) enz1 = CPsf(8) f_sp = np.linspace(-3, 3, 9) enz1.make_cart_grid(x_sp=np.linspace(-1, 1, 10), y_sp=np.linspace(-2, 2, 11), f_sp=np.linspace(-3, 3, 12)) enz1.czern.make_pol_grid(rho_j, theta_i) # create tmp path tmpfile = NamedTemporaryFile() tmppath = tmpfile.name tmpfile.close() enz1.save(tmppath) enz2 = CPsf.load(tmppath) for i in range(f_sp.size): beta = normal(size=enz1.czern.nk) + 1j * normal(size=enz1.czern.nk) self.assertTrue( norm( enz1.eval_grid_f(beta, i).ravel() - enz2.eval_grid_f(beta, i).ravel()) < self.max_enorm) self.assertTrue(norm(enz1.Ugrid.ravel() - enz2.Ugrid.ravel()) == 0) self.assertTrue(norm(enz1.Vnm.ravel() - enz2.Vnm.ravel()) == 0) self.assertTrue(norm(enz1.Cnm.ravel() - enz2.Cnm.ravel()) == 0) self.assertTrue(norm(enz1.czern.coefnorm - enz2.czern.coefnorm) == 0) self.assertTrue(norm(enz1.czern.ntab - enz2.czern.ntab) == 0) self.assertTrue(norm(enz1.czern.mtab - enz2.czern.mtab) == 0) self.assertTrue(enz1.czern.n == enz2.czern.n) self.assertTrue(enz1.czern.nk == enz2.czern.nk) self.assertTrue(enz1.czern.normalise == enz2.czern.normalise) self.assertTrue(norm(enz1.czern.rhoitab - enz2.czern.rhoitab) == 0) self.assertTrue(norm(enz1.czern.rhotab - enz2.czern.rhotab) == 0) self.assertTrue(enz1.czern.numpy_dtype == enz2.czern.numpy_dtype) self.assertTrue(norm(enz1.czern.ZZ - enz2.czern.ZZ) == 0) os.unlink(tmppath)
def test_eval_U_grid2(self): log = logging.getLogger('TestCPsf.test_eval_U_grid2') enz = CPsf(8) L, K, P = 50, 70, 3 A = L * K * P r_sp = np.linspace(.01, 2, L) ph_sp = [2 * math.pi * i / L for i in range(K)] f_sp = [normal(size=1, ) for i in range(P)] t1 = time() enz.make_pol_grid(r_sp, ph_sp, f_sp) t2 = time() log.debug('make_pol_grid {:.6f}'.format(t2 - t1)) self.assertTrue(enz.Ugrid.size == A * enz.czern.nk) beta = normal(size=enz.czern.nk) + 1j * normal(size=enz.czern.nk) T1 = np.zeros((L, K, P), order='F', dtype=np.complex) self.assertTrue(r_sp.size == L) self.assertTrue(len(ph_sp) == K) self.assertTrue(len(f_sp) == P) self.assertTrue(T1.size == L * K * P) log.debug(r_sp.size) t1 = time() for i, r in enumerate(r_sp): for j, ph in enumerate(ph_sp): for k, f in enumerate(f_sp): T1[i, j, k] = enz.U(beta, r, ph, f) t2 = time() log.debug('scalar {:.6f}'.format(t2 - t1)) t1 = time() T2 = np.dot(enz.Ugrid, beta) t2 = time() log.debug('vect {:.6f}'.format(t2 - t1)) log.debug(enz.Ugrid.flags) self.assertTrue(norm(T1.ravel() - T2.ravel()) < self.max_enorm)
def test_eval_U_grid2(self): log = logging.getLogger("TestCPsf.test_eval_U_grid2") enz = CPsf(8) L, K, P = 50, 70, 3 A = L * K * P r_sp = np.linspace(0.01, 2, L) ph_sp = [2 * math.pi * i / L for i in range(K)] f_sp = [normal(size=1) for i in range(P)] t1 = time() enz.make_pol_grid(r_sp, ph_sp, f_sp) t2 = time() log.debug("make_pol_grid {:.6f}".format(t2 - t1)) self.assertTrue(enz.Ugrid.size == A * enz.czern.nk) beta = normal(size=enz.czern.nk) + 1j * normal(size=enz.czern.nk) T1 = np.zeros((L, K, P), order="F", dtype=np.complex) self.assertTrue(r_sp.size == L) self.assertTrue(len(ph_sp) == K) self.assertTrue(len(f_sp) == P) self.assertTrue(T1.size == L * K * P) log.debug(r_sp.size) t1 = time() for i, r in enumerate(r_sp): for j, ph in enumerate(ph_sp): for k, f in enumerate(f_sp): T1[i, j, k] = enz.U(beta, r, ph, f) t2 = time() log.debug("scalar {:.6f}".format(t2 - t1)) t1 = time() T2 = np.dot(enz.Ugrid, beta) t2 = time() log.debug("vect {:.6f}".format(t2 - t1)) log.debug(enz.Ugrid.flags) self.assertTrue(norm(T1.ravel() - T2.ravel()) < 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_eval_U_grid1(self): log = logging.getLogger('TestCPsf.test_eval_U_grid1') enz = CPsf(8) r_sp = float(abs(normal(size=1, ))[0]) ph_sp = float(normal(size=1, )[0]) f_sp = float(normal(size=1, )[0]) enz.make_pol_grid([r_sp], [ph_sp], [f_sp]) beta = normal(size=enz.czern.nk) + 1j * normal(size=enz.czern.nk) a = enz.eval_grid(beta, 0, 0, 0) b = enz.U(beta, r_sp, ph_sp, f_sp) log.debug('r = {:e}, ph = {:e}, f = {:e}'.format(r_sp, ph_sp, f_sp)) log.debug('a {:s} {}'.format(str(type(a)), a)) log.debug('b {:s} {}'.format(str(type(b)), b)) log.debug('{}'.format(abs(a - b))) self.assertTrue(abs(a - b) < self.max_enorm)
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))
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
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))
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__': NA = 0.50 # numerical aperture diam = 0.25 # diameter [um] wavelength = 0.200 # lambda [um] eps = 0.00001 # offset to avoid division by zero radius = diam / 2 ap = 2 * pi * (NA / wavelength) * radius d = 1 / 8 * ap**2 + 1 / 384 * ap**4 + 1 / 10240 * ap**6 # optimal d. Why!? scale_z = wavelength / (2 * pi) * 1 / (1 - sqrt(1 - NA**2)) rspace = (np.arange(0, 0.5, 0.05) + eps) * NA / wavelength fspace = np.arange(-2, 2, 0.05) / scale_z + 1j * d cpsf = CPsf(0) # aberration free, only n = m = 0 t1 = time() field1 = cpsf.V(n=0, m=0, r=rspace, f=fspace) t2 = time() print('field1 {:.6f} sec'.format(t2 - t1)) field1 = np.squeeze(field1) I1 = np.square(np.abs(field1)) I1 *= (1 / I1.max()) ff, rr = np.meshgrid(np.real(fspace), rspace) levels = np.sort( np.concatenate((np.array([0.025, 0.05]), np.arange(0, 1, 0.1)))) c = p.contour(ff, rr, I1, levels) p.clabel(c, inline=1)
def test_save(self): rho_j = np.array( [ 0, 0.11111111111111, 0.22222222222222, 0.33333333333333, 0.44444444444444, 0.55555555555556, 0.66666666666667, 0.77777777777778, 0.88888888888889, 1, ] ) theta_i = np.array( [ 0, 0.69813170079773, 1.3962634015955, 2.0943951023932, 2.7925268031909, 3.4906585039887, 4.1887902047864, 4.8869219055841, 5.5850536063819, 6.2831853071796, ] ) enz1 = CPsf(8) f_sp = np.linspace(-3, 3, 9) enz1.make_cart_grid(x_sp=np.linspace(-1, 1, 10), y_sp=np.linspace(-2, 2, 11), f_sp=np.linspace(-3, 3, 12)) enz1.czern.make_pol_grid(rho_j, theta_i) # create tmp path tmpfile = NamedTemporaryFile() tmppath = tmpfile.name tmpfile.close() enz1.save(tmppath) enz2 = CPsf.load(tmppath) for i in range(f_sp.size): beta = normal(size=enz1.czern.nk) + 1j * normal(size=enz1.czern.nk) self.assertTrue( norm(enz1.eval_grid_f(beta, i).ravel() - enz2.eval_grid_f(beta, i).ravel()) < self.max_enorm ) self.assertTrue(norm(enz1.Ugrid.ravel() - enz2.Ugrid.ravel()) == 0) self.assertTrue(norm(enz1.Vnm.ravel() - enz2.Vnm.ravel()) == 0) self.assertTrue(norm(enz1.Cnm.ravel() - enz2.Cnm.ravel()) == 0) self.assertTrue(norm(enz1.czern.coefnorm - enz2.czern.coefnorm) == 0) self.assertTrue(norm(enz1.czern.ntab - enz2.czern.ntab) == 0) self.assertTrue(norm(enz1.czern.mtab - enz2.czern.mtab) == 0) self.assertTrue(enz1.czern.n == enz2.czern.n) self.assertTrue(enz1.czern.nk == enz2.czern.nk) self.assertTrue(enz1.czern.normalise == enz2.czern.normalise) self.assertTrue(norm(enz1.czern.rhoitab - enz2.czern.rhoitab) == 0) self.assertTrue(norm(enz1.czern.rhotab - enz2.czern.rhotab) == 0) self.assertTrue(enz1.czern.numpy_dtype == enz2.czern.numpy_dtype) self.assertTrue(norm(enz1.czern.ZZ - enz2.czern.ZZ) == 0) os.unlink(tmppath)