import torch
import numpy as np
from colibri.optics.functional import get_spatial_coords, circular_aperture
def nbk7_refractive_index(wavelength):
r"""
nbk refractive index at a given wavelength
Args:
wavelength: Wavelength in meters
Returns:
val: Refractive index - 1
"""
wavelength_squared = (wavelength * 1e6)**2
n_power2_minus_1 = (1.03961212 * wavelength_squared )/(wavelength_squared - 0.00600069867) + (0.231792344 * wavelength_squared) / (wavelength_squared - 0.0200179144) + (1.01046945 * wavelength_squared) / (wavelength_squared - 103.560653)
n = np.sqrt(n_power2_minus_1 + 1)
return n - 1
def spiral_refractive_index(wavelength):
r"""
Spiral refractive index at a given wavelength
Args:
wavelength: Wavelength in meters
Returns:
val: Refractive index - 1
"""
wavelength = (wavelength * 1e6)
IdLens = 1.5375+0.00829045*wavelength**(-2)-0.000211046*wavelength**(-4)
val = IdLens-1
return val
[docs]
def spiral_doe(M: int, N: int, number_spirals: int, radius: float, focal: float, start_w = 450e-9, end_w = 650e-9):
r"""
Code to generate a spiral DOE with a given number of spirals, radius, focal length and wavelength range.
For more information, please refer to the following paper: (2019). Compact snapshot hyperspectral imaging with diffracted rotation.
Args:
M (int): Resolution at Y axis in pixels.
N (int): Resolution at X axis in pixels.
number_spirals (int): Number of spirals.
radius (float): Radius of the doe.
focal (float): Focal length of the doe.
start_w (float): Initial design wavelength.
end_w (float): Final design wavelength.
Returns:
torch.Tensor: Height map of the spiral DOE
torch.Tensor: Aperture of the spiral DOE
"""
pixel_size = (2*radius)/np.min([M, N])
r, theta = get_spatial_coords(M = M, N = N, pixel_size = pixel_size, type='polar')
aperture = circular_aperture(M = M, N = N, radius = radius, pixel_size = pixel_size)
theta = torch.remainder(theta + torch.pi,
(2 * torch.pi / number_spirals))
lt = start_w + (end_w - start_w) * number_spirals * theta / 2 / torch.pi
n = torch.true_divide((torch.sqrt(r**2 + focal**2) - focal), lt) # Constructive interference
n = torch.ceil(n+1e-6)
height_map = (n * lt - (torch.sqrt(r**2 + focal**2) - focal)) / spiral_refractive_index(wavelength=lt) # Heights
return height_map * aperture, aperture
[docs]
def conventional_lens(M: int, N: int, focal = None, radius = None):
r"""
Code to generate a conventional lens with a given focal length and radius following the equation
.. math::
h(x, y) = \frac{-(x^2 + y^2)}{f}
where :math:`r` is the distance from the center of the lens and :math:`f` is the focal length of the lens.
For more information, please refer to:
Goodman, J. W. (2005). Introduction to Fourier optics. Roberts and Company Publishers.
(2017). Design and fabrication of diffractive optical elements with MATLAB.
Args:
M: Number of pixels in the y direction,
N: Number of pixels in the x direction,
focal: Focal length of the lens
wavelength: Wavelength of the light
radius: Radius of the lens
Returns:
torch.Tensor: Height map of the conventional lens
torch.Tensor: Aperture of the conventional lens
"""
pixel_size = (2*radius)/np.min([M, N])
r, _ = get_spatial_coords(M = M, N = N, pixel_size = pixel_size, type='polar')
aperture = circular_aperture(M = M, N = N, radius = radius, pixel_size = pixel_size)
height_map = -(r**2)/(focal)
return height_map*aperture, aperture