Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Projecting onto a particular Zernike #8

Open
jaredsagendorf opened this issue Apr 2, 2021 · 1 comment
Open

Projecting onto a particular Zernike #8

jaredsagendorf opened this issue Apr 2, 2021 · 1 comment

Comments

@jaredsagendorf
Copy link

jaredsagendorf commented Apr 2, 2021

Hello, suppose I have a function (or equivalently ).

What I would like to do is compute the integral (numerically):
for a given n,m

I'm not sure if this is possible with your code, but if so any advice to get started? Thanks!

@Jufevic
Copy link
Contributor

Jufevic commented May 24, 2021

Hello, you could try this:

from zernike import RZern
import numpy as np


def nm2noll(n, m):
    """Convert indices `(n, m)` to the Noll's index `k`."""
    k = n * (n + 1) // 2 + abs(m)
    if (m <= 0 and n % 4 in (0, 1)) or (m >= 0 and n % 4 in (2, 3)):
        k += 1
    return k


def zernike_moment(f, n, m):
    """Compute the projection of the function `f` over `Z_{nm}`.

    :math: `\iint f(x, y) Z_{nm}(x, y) dx dy`
    """
    k = nm2noll(n, m) - 1
    pupil = RZern(n)
    K, L = f.shape
    ddy = np.linspace(-1.0, 1.0, K)
    ddx = np.linspace(-1.0, 1.0, L)
    xv, yv = np.meshgrid(ddx, ddy)
    pupil.make_cart_grid(xv, yv)
    Zk = pupil.matrix(pupil.ZZ[:, k])
    integral = np.nansum(f * Zk)
    return integral / 4

Then, for instance imagine that f is a function that equals to one at every point:

f = np.ones((42, 42))
integral = zernike_moment(f, 1, 1)

Explanation

  • This library uses Noll's indexing, that means that if you only know the (n, m) indices of the Zernike polynomial, your first need to convert it as I did in the nm2noll function.
  • Then I initialized the Zernike polynomials up to the radial order n.
  • With pupil.make_cart_grid, I calculated the Zernike coefficients on a cartesian grid defined by the shape of f.
  • Finally to compute the integral, I summed the element-wise multiplication or f and Zk. This gives us an integral. I used np.nansum to ignore nan values in the sum.

Still I'm not certain that the normalization at the end is correct, maybe the result should only be integral. But I hope this will help you getting started!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants