NeuroOpticsTest / fraunhofer_test.py
Niccko's picture
Add download button
d1d7e79
Raw
History Blame Contribute Delete
5.34 kB
import matplotlib.pyplot as plt
import cupy as cp
import numpy as np
import math
from numpy.fft import fft2, fftshift, ifftshift
from cupyx.scipy import fft as fft_gpu
from zern_generator import Zernike
def denoise(screen: np.ndarray):
return np.where(np.abs(screen) < 1e-4, 0, screen)
class FraunhoferGPU:
def __init__(self, zernike: Zernike):
self.focal_distance = 100 * 10 ** -3
self.distance = 100 * 10 ** -3
self.radius = 5 * 10 ** -3
self.span = (-(10 ** -2), 10 ** -2)
self.wavelength = 500 * 10 ** -9
self.k = 2*math.pi/self.wavelength
self.zernike = zernike
def get_focal_point(self,input_screen):
input_screen_gpu = cp.asarray(input_screen)
xv = cp.asarray(self.zernike.xv)
yv = cp.asarray(self.zernike.yv)
phase_mul = ((cp.exp(1j*self.k*self.distance) * cp.exp(1j*self.k*(xv**2 + yv**2)/(2*self.distance)))/(1j*self.wavelength*self.distance))
U_fraun = fft_gpu.fft2(fft_gpu.ifftshift(input_screen_gpu), overwrite_x=True)
U_fraun = fftshift(U_fraun * phase_mul)
I_fraun = cp.abs(U_fraun)**2
return I_fraun / cp.max(I_fraun)
def generate_diff(self, defocus_amount, *zernikes):
zernikes = list(zernikes)
if len(zernikes) < 5:
zernikes += [0] * (5-len(zernikes))
wf = self.zernike.generate_zern_screen([1], self.radius)
f_plus = self.zernike.generate_zern_screen(self.zernike.add_defocus(defocus_amount,zernikes), norm_radius=self.radius)
f_minus = self.zernike.generate_zern_screen(self.zernike.add_defocus(-defocus_amount,zernikes), norm_radius=self.radius)
wf_c = cp.asarray(wf)
f_plus_c = cp.asarray(f_plus)
f_minus_c = cp.asarray(f_minus)
focal_image_plus = denoise(self.get_focal_point(wf_c*cp.exp(f_plus_c * 1j)))
focal_image_minus = denoise(self.get_focal_point(wf_c*cp.exp(f_minus_c * 1j)))
return (
cp.asnumpy(focal_image_plus),
cp.asnumpy(focal_image_minus),
cp.asnumpy(focal_image_plus - focal_image_minus)
)
class Fraunhofer:
def __init__(self, zernike: Zernike):
self.focal_distance = 100 * 10 ** -3
self.distance = 100 * 10 ** -3
self.radius = 5 * 10 ** -3
self.span = (-(10 ** -2), 10 ** -2)
self.wavelength = 500 * 10 ** -9
self.k = 2*math.pi/self.wavelength
self.zernike = zernike
# def _denoise(screen: np.ndarray):
# return np.where(np.abs(screen) < 1e-4, 0, screen)
def get_focal_point(self,input_screen):
input_screen_gpu = np.asarray(input_screen)
phase_mul = ((np.exp(1j*self.k*self.distance) * np.exp(1j*self.k*(self.zernike.xv**2 + self.zernike.yv**2)/(2*self.distance)))/(1j*self.wavelength*self.distance))
U_fraun = fft2(ifftshift(input_screen_gpu))
U_fraun = fftshift(U_fraun * phase_mul)
#U_fraun = fftshift(U_fraun)
I_fraun = np.abs(U_fraun)**2
return I_fraun / np.max(I_fraun)
def generate_diff(self, defocus_amount, *zernikes):
zernikes = list(zernikes)
if len(zernikes) < 5:
zernikes += [0] * (5-len(zernikes))
wf = self.zernike.generate_zern_screen([1], self.radius)
f_plus = self.zernike.generate_zern_screen(
self.zernike.add_defocus(defocus_amount,zernikes),
norm_radius=self.radius
)
f_minus = self.zernike.generate_zern_screen(
self.zernike.add_defocus(-defocus_amount,zernikes),
norm_radius=self.radius
)
wf_c = np.asarray(wf)
f_plus_c = np.asarray(f_plus)
f_minus_c = np.asarray(f_minus)
focal_image_plus = denoise(
self.get_focal_point(wf_c*np.exp(f_plus_c * 1j))
)
focal_image_minus = denoise(
self.get_focal_point(wf_c*np.exp(f_minus_c * 1j))
)
diff = focal_image_plus - focal_image_minus
normalized_diff = diff / cp.max(diff)
return (
cp.asnumpy(focal_image_plus),
cp.asnumpy(focal_image_minus),
cp.asnumpy(normalized_diff)
)
if __name__ == "__main__":
zernike = Zernike()
zernike.set_image_params(npix=2 ** 8)
zoom_factor = 20
f = Fraunhofer(zernike=zernike)
ratio = (f.wavelength*f.focal_distance)/f.radius
zernikes = [[1 if i == j else 0 for i in range(0,24)] for j in range(20,24)]
print(zernikes)
fig, ax = plt.subplots(4,1)
for i, z in enumerate(zernikes):
print(zernike._osa_to_noll_list(z))
wf_a = zernike.generate_zern_screen([1], 0.01/zoom_factor)
wf_c = zernike.generate_zern_screen(z, 0.01/zoom_factor)
wf_c_nz = zernike.generate_zern_screen(z, 0.01)
wf = wf_a * np.exp(wf_c*1j)
focal = f.get_focal_point(wf)
zoom = ratio*zoom_factor
#ax[i][0].imshow(np.abs(wf_c_nz))
ax[i].imshow(np.abs(focal))
ax[i].imshow(np.abs(focal))
ax[0].set_title("Zernike 5 - DEFOCUS")
ax[1].set_title("Zernike 6 - V-PR-ASTIGMATISM")
ax[2].set_title("Zernike 7 - V-TREFOIL")
ax[3].set_title("Zernike 8 - V-PR_COMA")
ax[0].axis('off')
ax[1].axis('off')
ax[2].axis('off')
ax[3].axis('off')
plt.show()