Skip to content

Commit

Permalink
New testing fixtures and propagate_fft test
Browse files Browse the repository at this point in the history
  • Loading branch information
andykee committed Nov 27, 2023
1 parent e3e0842 commit 581b349
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
12 changes: 12 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# ref: https://gist.github.com/peterhurford/09f7dcda0ab04b95c026c60fa49c2a68?permalink_comment_id=3453153#gistcomment-3453153

from glob import glob


def refactor(string: str) -> str:
return string.replace("/", ".").replace("\\", ".").replace(".py", "")


pytest_plugins = [
refactor(fixture) for fixture in glob("tests/fixtures/*.py") if "__" not in fixture
]
36 changes: 36 additions & 0 deletions tests/fixtures/airy2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest

import numpy as np
import scipy.special

@pytest.fixture
def airy2():

def _airy2(diameter, focal_length, wavelength, pixelscale, shape, oversample):
# https://en.wikipedia.org/wiki/Airy_disk#Mathematical_Formulation

f_number = focal_length / diameter

shape = np.asarray(shape)
shape *= oversample

c = (shape - 1) / 2
y, x = np.indices(shape, dtype=float)

x -= c[1]
y -= c[0]

x *= (pixelscale[0] / oversample)
y *= (pixelscale[1] / oversample)

q = np.sqrt(x ** 2 + y ** 2)
X = (np.pi * q) / (wavelength * f_number)

# if length is odd, the center value will be zero which will throw a
# divide by zero error. To avoid this, we'll set any zeros to machine
# epsilon (eps)
X[X == 0] = np.finfo(X.dtype).eps

return (2 * scipy.special.jn(1, X) / X) ** 2

return _airy2
25 changes: 25 additions & 0 deletions tests/fixtures/pupil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pytest

import lentil

@pytest.fixture
def pupil():

def _pupil(focal_length, diameter, shape, radius, coeffs=None):

amplitude = lentil.circle(shape, radius)
pixelscale = diameter/(2*radius)

if coeffs is not None:
opd = lentil.zernike_compose(amplitude, coeffs)
else:
opd = 0

p = lentil.Pupil(amplitude=amplitude,
phase=opd,
pixelscale=pixelscale,
focal_length=focal_length)

return p

return _pupil
28 changes: 28 additions & 0 deletions tests/test_propagate_fft.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import lentil
import numpy as np


def test_propagate_airy(airy2, pupil):
diameter = 1
focal_length = 10
wavelength = 500e-9
pixelscale = (5e-6, 5e-6)
shape = (511, 511)
oversample = 1

psf_airy = airy2(diameter, focal_length, wavelength, pixelscale, shape, oversample)
psf_airy = psf_airy/np.max(psf_airy)

p = pupil(focal_length=focal_length,
diameter=diameter,
shape=(512, 512),
radius=256,
coeffs=None)

w = lentil.Wavefront(wavelength=500e-9)
w *= p
w = lentil.propagate_fft(w, shape=(511,511), pixelscale=5e-6, oversample=1)
psf = w.intensity
psf = psf/np.max(psf)

np.all(np.isclose(psf, psf_airy, atol=1e-3))

0 comments on commit 581b349

Please sign in to comment.