mirror of
https://github.com/yosata/fourierOptics.git
synced 2026-10-29 20:51:10 +00:00
120 lines
4.2 KiB
Python
120 lines
4.2 KiB
Python
# from .__init__ import __data_dir__
|
|
import numpy as np
|
|
import os
|
|
from astropy.io import fits
|
|
from scipy import interpolate
|
|
|
|
|
|
|
|
class Profiles:
|
|
def __init__(self):
|
|
pass
|
|
|
|
def top_hat(self, r, n, m, dpix, oversample=1, dx=0, dy=0):
|
|
j,i = np.mgrid[-n/2*dpix : n/2*dpix : 1j*n*oversample, -m/2*dpix : m/2*dpix : 1j*m*oversample]
|
|
dist_from_center = np.sqrt((i-dx)**2 + (j-dy)**2)
|
|
_Anew = (dist_from_center <= (r)).astype(int)
|
|
return _Anew
|
|
|
|
|
|
def obscured_top_hat(self, r1, r2, n, m, dpix, oversample=1):
|
|
'''
|
|
Creates a grid of n x m points, following a top hat function
|
|
where all points inside a radius r is 1 and 0 otherwise.
|
|
'''
|
|
assert r1 > r2, "r2 < r1, change input"
|
|
j,i = np.mgrid[-n/2*dpix : n/2*dpix : 1j*n*oversample, -m/2*dpix : m/2*dpix : 1j*m*oversample]
|
|
dist_from_center = np.sqrt(i**2 + j**2)
|
|
_Anew = (dist_from_center <= (r1)) & (dist_from_center >= (r2))
|
|
return _Anew.astype(int)
|
|
|
|
|
|
def spider_top_hat(self, r1, r2, n, m, dpix, oversample=1):
|
|
'''
|
|
Creates a grid of n x m points, following a top hat function
|
|
where all points inside a radius r is 1 and 0 otherwise.
|
|
'''
|
|
assert r1 > r2, "r2 < r1, change input"
|
|
j,i = np.mgrid[-n/2*dpix : n/2*dpix : 1j*n*oversample, -m/2*dpix : m/2*dpix : 1j*m*oversample]
|
|
n *= oversample
|
|
m *= oversample
|
|
dist_from_center = np.sqrt(i**2 + j**2)
|
|
_Anew = (dist_from_center <= (r1)) & (dist_from_center >= (r2))
|
|
_Aspider = (np.abs(i) < (0.05*r1)) | (np.abs(j) < (0.05*r1))
|
|
_Anew = _Anew & ~_Aspider
|
|
return _Anew
|
|
|
|
|
|
def gaussian(self, r, n, m, dpix, oversample=1, dx=0, dy=0):
|
|
'''
|
|
Creates a grid of n x m points, following a gaussian function
|
|
where the radius r is the FWHM of the gaussian shape.
|
|
'''
|
|
j,i = np.mgrid[-n/2*dpix : n/2*dpix : 1j*n*oversample, -m/2*dpix : m/2*dpix : 1j*m*oversample]
|
|
dist_from_center = np.sqrt((i-dx)**2 + (j-dy)**2)
|
|
return np.exp(-((j-dx)**2 + (i-dy)**2) / r**2)
|
|
|
|
|
|
def ELT_pupil(self, n, m, dpix):
|
|
# Find data directory
|
|
__pkg_dir__ = os.path.dirname(os.path.realpath(__file__))
|
|
__data_dir__ = os.path.join(__pkg_dir__, 'data')
|
|
_fits_image = __data_dir__ + '/ELT_M1_pupil_profile.fits'
|
|
_ELT_pupil = fits.open(_fits_image)[0].data
|
|
_ELT_inner_diam = 38542 # all glass diameter of M1 in mm
|
|
_dpix_fits = _ELT_inner_diam / 623 # pixels on the diameter filled with 'glass'
|
|
_resx, _resy = np.shape(_ELT_pupil)
|
|
_xf = np.linspace(-_resx/2*_dpix_fits, _resx/2*_dpix_fits, _resx)
|
|
_yf = np.linspace(-_resy/2*_dpix_fits, _resy/2*_dpix_fits, _resy)
|
|
_f_pupil = interpolate.interp2d(_xf, _yf, _ELT_pupil, kind='linear')
|
|
_x = np.linspace(-n/2*dpix, n/2*dpix, n)
|
|
_y = np.linspace(-m/2*dpix, m/2*dpix, m)
|
|
_ELT_pupil = _f_pupil(_x, _y)
|
|
return _ELT_pupil
|
|
|
|
|
|
def bahtinov_mask(self, r1, r2, n, m, dpix, N, oversample=1, half_width_spiders=None):
|
|
'''
|
|
Creates a Bahtinov mask profile.
|
|
This profile is a popular mask to focus a telescope in the
|
|
amateur community.
|
|
'''
|
|
assert r1 > r2, "r2 < r1, change input"
|
|
|
|
if half_width_spiders is None:
|
|
half_width_spiders = 0.03 * r1
|
|
|
|
# Obscured top hat
|
|
j,i = np.mgrid[-n/2*dpix : n/2*dpix : 1j*n*oversample, -m/2*dpix : m/2*dpix : 1j*m*oversample]
|
|
dist_from_center = np.sqrt(i**2 + j**2)
|
|
_Anew = (dist_from_center <= (r1)) & (dist_from_center >= (r2))
|
|
_Anew = _Anew.astype(int)
|
|
|
|
# Three quadrants of Bahtinov mask
|
|
_M1 = (i < -half_width_spiders)
|
|
_M2 = (i > half_width_spiders) & (j > half_width_spiders)
|
|
_M3 = (i > half_width_spiders) & (j < -half_width_spiders)
|
|
_MC = _M1 | _M2 | _M3
|
|
|
|
# Generating the lines
|
|
_d = 2 * r1 / int(N)
|
|
_M4 = step(j, i, period=_d, rotation=0)
|
|
_M5 = step(j, i, period=_d, rotation=30)
|
|
_M6 = step(j, i, period=_d, rotation=-30)
|
|
_MC = (_M1 & _M4) | (_M2 & _M5) | (_M3 & _M6)
|
|
|
|
# Combining with the obscured top hat
|
|
_Anew = _Anew * _MC
|
|
return _Anew.astype(int)
|
|
|
|
|
|
def step(x, y, period=1, rotation=0):
|
|
'''
|
|
Function that returns a 2D square wave with period and rotation.
|
|
'''
|
|
theta = np.deg2rad(rotation)
|
|
xn = x * np.cos(theta) - y * np.sin(theta)
|
|
yn = x * np.sin(theta) + y * np.cos(theta)
|
|
a = ((2/period * xn ).astype(int) % 2) & (xn>= 0)
|
|
b = ((2/period * xn - 1).astype(int) % 2) & (xn< 0)
|
|
return a + b |