Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    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))
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
    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))
Ejemplo n.º 13
0
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)
Ejemplo n.º 15
0
    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)