예제 #1
0
    def V(self, n, m, r, f, L_max=35, ncpus=-1):
        r"""Evaluate :math:`V_n^m(r, f)`.

        Compute

        .. math::

            V_n^m(r, f) = \epsilon_m \exp(if) \sum_{l=1}^{L_max}(-2if)^{l - 1}
                \sum_{j=0}^{(n - |m|)/2} v_{l,j}
                (1/l(2\pi r)^l)J_{|m| + l + 2j}(2\pi r).

        See Eq. (2.48) in [B2008]_.

        Parameters
        ----------
        -   `n`: `numpy` vector of integers for the radial orders `n`
        -   `m`: `numpy` vector of integers for the azimuthal frequencies `m`
        -   `r`: `numpy` vector of doubles for the radial coordinate :math:`r`,
            which is normalised to the diffraction unit `wavelength/NA`
        -   `f`: `numpy` vector of complex numbers for the defocus parameter,
            see [J2002]_, [B2008]_, and [H2010]_
        -   `L_max`: optional `int` for the truncation order of the series,
            see [J2002]_, [B2008]_, and [H2010]_. `L_max <= 0` uses the
            default value of `35`.
        -   `ncpus` : optional `int` for the number of threads. `-1` chooses
            all available cpus

        Returns
        -------
        -   `vnm`: `numpy` array of shape `(r.size, f.size, n.size)` for
            :math:`V_n^m(r, f)`

        References
        ----------
        ..  [J2002] A. J. E. M. Janssen, "Extended Nijboer–Zernike approach
            for the computation of optical point-spread functions," J. Opt.
            Soc.  Am.  A 19, 849–857 (2002). `doi
            <http://dx.doi.org/10.1364/JOSAA.19.000849>`__.
        ..  [B2008] J. Braat, S. van Haver, A. Janssen, P. Dirksen, Chapter 6
            Assessment of optical systems by means of point-spread functions,
            In: E. Wolf, Editor(s), Progress in Optics, Elsevier, 2008, Volume
            51, Pages 349-468, ISSN 0079-6638, ISBN 9780444532114. `doi
            <http://dx.doi.org/10.1016/S0079-6638(07)51006-1>`__.
        ..  [H2010] S. van Haver, The Extended Nijboer-Zernike Diffraction
            Theory and its Applications (Ph.D. thesis, Delft University of
            Technology, The Netherlands, 2010). `doi
            <http://resolver.tudelft.nl/uuid:8d96ba75-24da-4e31-a750-1bc348155061>`__.

        """
        n = self._numpify(n, np.int)
        m = self._numpify(m, np.int)
        r = self._numpify(r, np.float)
        f = self._numpify(f, np.complex)

        Vnm = vnmpocnp(r, f, n, m, L_max=L_max, ncpus=ncpus)

        if Vnm.size == 1:
            return complex(Vnm[0, 0, 0])
        else:
            return Vnm
예제 #2
0
    def U(self, beta, r, phi, f):
        r"""Evaluate the complex point spread function at a point.

        The complex point-spread function is

        .. math::

            U(r, \phi, f) = 2 \sum_{n, m} \beta_{n}^{m}
                \sqrt{n + 1} i^{m} V_n^m(r, f) \exp(im\phi).

        See Eq. (4) in [A2015]_.

        Parameters
        ----------
        -   `beta`: `list` of the complex Zernike coefficients
            :math:`\beta_n^m`
        -   `r`: float for the radial coordinate :math:`r`, normalised to
            the diffraction unit `wavelength/NA`
        -   `phi`: float for the azimuthal coordinate :math:`\phi`
        -   `f`: complex-valued defocus parameter, see [J2002]_, [B2008]_, and
            [H2010]_

        Returns
        -------
        -   `U`: complex value of :math:`U(r, \phi, f)`

        References
        ----------
        ..  [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>`__.
        ..  [J2002] A. J. E. M. Janssen, "Extended Nijboer–Zernike approach
            for the computation of optical point-spread functions," J. Opt.
            Soc.  Am.  A 19, 849–857 (2002). `doi
            <http://dx.doi.org/10.1364/JOSAA.19.000849>`__.
        ..  [B2008] J. Braat, S. van Haver, A. Janssen, P. Dirksen, Chapter 6
            Assessment of optical systems by means of point-spread functions,
            In: E. Wolf, Editor(s), Progress in Optics, Elsevier, 2008, Volume
            51, Pages 349-468, ISSN 0079-6638, ISBN 9780444532114. `doi
            <http://dx.doi.org/10.1016/S0079-6638(07)51006-1>`__.
        ..  [H2010] S. van Haver, The Extended Nijboer-Zernike Diffraction
            Theory and its Applications (Ph.D. thesis, Delft University of
            Technology, The Netherlands, 2010). `doi
            <http://resolver.tudelft.nl/uuid:8d96ba75-24da-4e31-a750-1bc348155061>`__.

        """
        U = complex(0.0)
        r = self._numpify(r, np.float)
        f = self._numpify(f, np.complex)
        assert (r.size == 1)
        assert (f.size == 1)
        n, m = np.array([0]), np.array([0])
        for i in range(self.czern.nk):
            n[0], m[0] = self.czern.ntab[i], self.czern.mtab[i]
            cf = self.czern.coefnorm[i]
            U += complex(beta[i] * cf * ((1j)**m[0]) *
                         vnmpocnp(r, f, n, m)[0][0][0] *
                         cmath.exp(1j * m[0] * phi))
        return 2.0 * U
예제 #3
0
    def test_vnmpocnp(self):
        data = h5py.File('refVnmpo.h5', 'r')

        ref = data['ref'].value
        r = data['r'].value
        f = data['f'].value
        n = data['n'].value
        m = data['m'].value

        data.close()

        out = vnmpocnp(r, f, n, m)
        self.assertTrue(out.shape[0] == r.size)
        self.assertTrue(out.shape[1] == r.size)
        self.assertTrue(out.shape[2] == n.size)
        err = norm((out - ref).ravel())
        self.assertTrue(err < self.max_enorm)
예제 #4
0
    def test_vnmpocnp(self):
        data = h5py.File('refVnmpo.h5', 'r')

        ref = data['ref'].value
        r = data['r'].value
        f = data['f'].value
        n = data['n'].value
        m = data['m'].value

        data.close()

        out = vnmpocnp(r, f, n, m)
        self.assertTrue(out.shape[0] == r.size)
        self.assertTrue(out.shape[1] == r.size)
        self.assertTrue(out.shape[2] == n.size)
        err = norm((out - ref).ravel())
        self.assertTrue(err < self.max_enorm)
예제 #5
0
    def make_pol_grid(self, r_sp=None, ph_sp=None, f_sp=None, min_r=1e-9):
        r"""Make a polar grid for the complex point-spread function.

        The complex point-spread function is

        .. math::

            U(r, \phi, f) = 2 \sum_{n, m} \beta_{n}^{m}
                \sqrt{n + 1} i^{m} V_n^m(r, f) \exp(im\phi).

        See Eq. (4) in [A2015]_.

        Parameters
        ----------
        -   `r_sp`: `numpy` array of the radial coordinate :math:`r`
        -   `ph_sp`: `numpy` array of the azimuthal coordinate :math:`\phi`
        -   `f_sp`: `numpy` array of complex numbers for the defocus parameter,
            see [J2002]_, [B2008]_, [H2010]_
        -   `min_r`: float, optional threshold to avoid division by zero in
            the image plane

        References
        ----------
        ..  [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>`__.
        ..  [J2002] A. J. E. M. Janssen, "Extended Nijboer–Zernike approach
            for the computation of optical point-spread functions," J. Opt.
            Soc.  Am.  A 19, 849–857 (2002). `doi
            <http://dx.doi.org/10.1364/JOSAA.19.000849>`__.
        ..  [B2008] J. Braat, S. van Haver, A. Janssen, P. Dirksen, Chapter 6
            Assessment of optical systems by means of point-spread functions,
            In: E. Wolf, Editor(s), Progress in Optics, Elsevier, 2008, Volume
            51, Pages 349-468, ISSN 0079-6638, ISBN 9780444532114. `doi
            <http://dx.doi.org/10.1016/S0079-6638(07)51006-1>`__.
        ..  [H2010] S. van Haver, The Extended Nijboer-Zernike Diffraction
            Theory and its Applications (Ph.D. thesis, Delft University of
            Technology, The Netherlands, 2010). `doi
            <http://resolver.tudelft.nl/uuid:8d96ba75-24da-4e31-a750-1bc348155061>`__.

        """
        r_sp = self._numpify(r_sp, np.float).ravel(order='F')
        ph_sp = self._numpify(ph_sp, np.float).ravel(order='F')
        f_sp = self._numpify(f_sp, np.complex).ravel(order='F')

        # remove nans due to r = 0.0
        r_sp = self._trim_r(r_sp, min_r)

        Ugrid = np.zeros((r_sp.size, ph_sp.size, f_sp.size, self.czern.nk),
                         order='F',
                         dtype=np.complex)
        Vnm = vnmpocnp(r_sp, f_sp, self.czern.ntab, self.czern.mtab)
        Cnm = np.zeros((ph_sp.size, self.czern.nk),
                       order='F',
                       dtype=np.complex)
        for k in range(self.czern.nk):
            m = self.czern.mtab[k]
            Cnm[:, k] = 2.0 * self.czern.coefnorm[k] * (
                (1j)**m) * np.exp(1j * m * ph_sp)
        for k in range(self.czern.nk):
            for f in range(f_sp.size):
                v = Vnm[:, f, k].reshape((Vnm.shape[0], 1))
                c = Cnm[:, k].reshape((1, Cnm.shape[0]))
                Ugrid[:, :, f, k] = np.kron(c, v)
        assert (np.all(np.isfinite(Ugrid)))
        self.Ugrid = Ugrid
        self.Vnm = Vnm
        self.Cnm = Cnm