def test_wavelength_invariance_propagate_angle(): planes = [TiltPupil(npix=256), BasicDetector()] psf_650 = lentil.propagate(planes, 650e-9, npix=(128, 128), oversample=2, rebin=False, tilt='phase') psf_900 = lentil.propagate(planes, 900e-9, npix=(128, 128), oversample=2, rebin=False, tilt='angle') psf_650 = psf_650 / np.max(psf_650) psf_900 = psf_900 / np.max(psf_900) psf_650[psf_650 < 1e-2] = 0 psf_900[psf_900 < 1e-2] = 0 delta = np.abs( np.asarray(lentil.util.centroid(psf_650)) - np.asarray(lentil.util.centroid(psf_900))) assert np.all(delta <= 5e-2)
def test_shape_invariance_propagate_angle(): pupil_sm = TiltPupil(npix=256) pupil_lg = TiltPupil(npix=512, coeffs=pupil_sm.coeffs) planes_sm = [pupil_sm, BasicDetector()] psf_sm = lentil.propagate(planes_sm, 650e-9, npix=(512, 512), oversample=2, rebin=True, npix_chip=64, tilt='angle') planes_lg = [pupil_lg, BasicDetector()] psf_lg = lentil.propagate(planes_lg, 650e-9, npix=(512, 512), oversample=2, rebin=True, npix_chip=64, tilt='angle') delta = np.abs( np.asarray(lentil.util.centroid(psf_sm)) - np.asarray(lentil.util.centroid(psf_lg))) assert np.all( delta <= 0.5 ) # can't reliably do better than about 1/20th pixel so we''l score against 1/10th
def test_wavelength_invariance_propagate_phase(): planes = [TiltPupil(npix=256), BasicDetector()] psf_650 = lentil.propagate(planes, 650e-9, npix=(128, 128), oversample=2, rebin=False, tilt='phase') psf_900 = lentil.propagate(planes, 900e-9, npix=(128, 128), oversample=2, rebin=False, tilt='angle') psf_650 = psf_650 / np.max(psf_650) psf_900 = psf_900 / np.max(psf_900) psf_650[psf_650 < 1e-2] = 0 psf_900[psf_900 < 1e-2] = 0 delta = np.abs( np.asarray(lentil.util.centroid(psf_650)) - np.asarray(lentil.util.centroid(psf_900))) assert np.all( delta <= 5e-2 ) # can't reliably do better than about 1/50th pixel so we''l score against 1/20th
def test_propagate_tilt_phase_flatten(): planes = [TiltPupil(npix=256), BasicDetector()] psf = lentil.propagate(planes, [650e-9, 700e-9], npix=(128, 128), rebin=False, tilt='phase', flatten=True) psf_stack = lentil.propagate(planes, [650e-9, 700e-9], npix=(128, 128), rebin=False, tilt='phase', flatten=False) assert np.array_equal(psf, np.sum(psf_stack, axis=0))
def test_propagate_tilt_angle_mono(): planes = [SimpleSegmentedPupil(npix=256), SimpleDetector()] psf_phase = lentil.propagate(planes, 650e-9, npix=(128, 128), oversample=2, rebin=False, tilt='phase') psf_angle = lentil.propagate(planes, 650e-9, npix=(128, 128), oversample=2, rebin=False, tilt='angle') # Normalize and threshold the PSFs so that the centroiding is consistent psf_phase /= np.max(psf_phase) psf_phase[psf_phase < 0.2] = 0 psf_angle /= np.max(psf_angle) psf_angle[psf_angle < 0.2] = 0 delta = np.abs(np.asarray(lentil.util.centroid(psf_phase)) - np.asarray(lentil.util.centroid(psf_angle))) assert np.all(delta <= 0.2)
def test_propagate_tilt_angle_analytic(): oversample = 10 npix = np.array([64, 64]) pupil = TiltPupil(npix=256) detector = BasicDetector() psf = lentil.propagate([pupil, detector], wave=650e-9, npix=npix, oversample=oversample, rebin=False, tilt='angle') psf = psf / np.max(psf) psf[psf < 0.2] = 0 # threshold for centroiding center = npix // 2 * oversample centroid = np.asarray(lentil.util.centroid(psf)) shift = centroid - center pupil_tilt = pupil.coeffs[1:3] # The factor of 4 gets you from RMS to PV analytic_shift = -((pupil_tilt / pupil.diameter) * pupil.focal_length / detector.pixelscale) * oversample * 4 assert np.all((np.abs(shift - analytic_shift) / oversample) < 0.2)
def test_amplitude_normalize_power_oversample_rebin(): planes = [TiltPupil(npix=256), BasicDetector()] psf = lentil.propagate(planes, 650e-9, npix=(64, 64), oversample=2, rebin=False) assert (np.sum(psf) <= 1) and (np.sum(psf) >= 0.95)
def test_propagate_tilt_angle_mono(): planes = [TiltPupil(npix=256), BasicDetector()] psf_phase = lentil.propagate(planes, 650e-9, npix=(128, 128), oversample=2, rebin=False, tilt='phase') psf_angle = lentil.propagate(planes, 650e-9, npix=(128, 128), oversample=2, rebin=False, tilt='angle') # threshold the PSFs so that the centroiding is consistent psf_phase[psf_phase < 1e-5] = 0 psf_angle[psf_angle < 1e-5] = 0 delta = np.abs( np.asarray(lentil.util.centroid(psf_phase)) - np.asarray(lentil.util.centroid(psf_angle))) assert np.all(delta <= 1e-10)
def test_propagate_airy(): # we set oversample = 1 and apply an "oversampling" factor of 25 to pixelscale # so that we can more easily enforce an odd npix. having an odd npix enables # comparison between numerical propagations via dft2() and the airy2() function # since their DC pixels will be coincident. p = TiltPupil(npix=512, coeffs=[0]) d = BasicDetector(pixelscale=5e-6 / 25) psf_airy = airy2(diameter=p.diameter, focal_length=p.focal_length, wavelength=650e-9, pixelscale=d.pixelscale, shape=(511, 511), oversample=1) psf_airy = psf_airy / np.max(psf_airy) planes = [p, d] psf = lentil.propagate(planes, wave=650e-9, npix=511, oversample=1) psf = psf / np.max(psf) assert np.all(np.isclose(psf, psf_airy, atol=1e-3))
import matplotlib.pyplot as plt import lentil mask = lentil.util.circle((256, 256), 128) opd = lentil.zernike.zernike(mask, 8) * 500e-9 # 500 nm of coma pupil = lentil.Pupil(amplitude=mask, phase=opd, diameter=1, focal_length=10, pixelscale=1/256) rotation = lentil.Rotate(angle=30, unit='degrees') flip = lentil.Flip(1) detector = lentil.Detector(pixelscale=5e-6, shape=(1024, 1024)) psf = lentil.propagate([pupil, detector], wave=650e-9, npix=(128, 128)) plt.imshow(psf, origin='lower') plt.savefig('../../_static/img/psf_coma.png', transparent=True, bbox_inches='tight', dpi=150) psf = lentil.propagate([pupil, rotation, detector], wave=650e-9, npix=(128, 128)) plt.imshow(psf, origin='lower') plt.savefig('../../_static/img/psf_coma_rotate.png', transparent=True, bbox_inches='tight', dpi=150) psf = lentil.propagate([pupil, flip, detector], wave=650e-9, npix=(128, 128)) plt.imshow(psf, origin='lower') plt.savefig('../../_static/img/psf_coma_flip.png', transparent=True, bbox_inches='tight', dpi=150)
import matplotlib.pyplot as plt import lentil pupil = lentil.Pupil(amplitude=lentil.util.circle((256, 256), 128), diameter=1, focal_length=10, pixelscale=1/256) detector = lentil.Detector(pixelscale=5e-6, shape=(1024, 1024)) psf = lentil.propagate([pupil, detector], wave=650e-9, npix=(64, 64)) plt.imshow(psf, origin='lower') plt.savefig('../../_static/img/psf_64.png', transparent=True, bbox_inches='tight', dpi=150) tilt = lentil.Tilt(x=10e-6, y=-5e-6) psf_tilt = lentil.propagate([tilt, pupil, detector], wave=650e-9, npix=(64, 64)) plt.imshow(psf_tilt, origin='lower') plt.savefig('../../_static/img/psf_64_tilt.png', transparent=True, bbox_inches='tight', dpi=150)
mask = lentil.util.circle((256, 256), 128) - lentil.util.circle( (256, 256), 128 / 3) opd = lentil.zernike.zernike_compose( mask, coeffs=[0, 0, 0, 300e-9, 50e-9, -100e-9, 50e-9]) pupil = lentil.Pupil(amplitude=mask, phase=opd, diameter=1, focal_length=10, pixelscale=1 / 256) detector = lentil.Image(pixelscale=5e-6) psf5 = lentil.propagate([pupil, detector], wave=650e-9, npix=32, oversample=10, rebin=False) psf = lentil.detector.pixelate(psf5, oversample=10) plt.imshow(mask) plt.savefig('../../_static/img/getting_started_amp.png', transparent=True, bbox_inches='tight', dpi=150) plt.close() plt.imshow(opd) plt.savefig('../../_static/img/getting_started_opd.png', transparent=True,