mirror of
https://github.com/yosata/fourierOptics.git
synced 2026-10-30 05:01:04 +00:00
Large update for finishing thesis
This commit is contained in:
1 parent
8e0575e0e9
commit
9ce4b7045f
25 files changed
+2025
-230
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -244,7 +244,7 @@ class ParaxialMICADO:
|
|||||||
if print_progress: print('Propagating from ELT-IFP to MCD-COL')
|
if print_progress: print('Propagating from ELT-IFP to MCD-COL')
|
||||||
Ein = Eout
|
Ein = Eout
|
||||||
if self.ELT_FP.wavefrontError:
|
if self.ELT_FP.wavefrontError:
|
||||||
Ein *= self.ELT_FP.phase_delay(x, y, l, ip_type='surface')
|
Ein *= self.ELT_FP.phase_delay(x, y, l, ip_type='phase')
|
||||||
Eout, x, y = fou.fresnel_propagation(Ein, x, y, dz=self.ELT_COL.f, oversample=None,
|
Eout, x, y = fou.fresnel_propagation(Ein, x, y, dz=self.ELT_COL.f, oversample=None,
|
||||||
show=show[s], save=saveList[s], outputCoordinates=output_coordinates[s],
|
show=show[s], save=saveList[s], outputCoordinates=output_coordinates[s],
|
||||||
apply_interpolation=apply_ip[s], tx=tilt_x[s], ty=tilt_y[s])
|
apply_interpolation=apply_ip[s], tx=tilt_x[s], ty=tilt_y[s])
|
||||||
|
|||||||
+190
-3
@@ -1,7 +1,10 @@
|
|||||||
|
'''
|
||||||
|
Summary
|
||||||
|
'''
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pickle
|
import pickle
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
from numba import njit
|
||||||
'''
|
'''
|
||||||
Miscellaneous functions that do not belong specifically to any of the
|
Miscellaneous functions that do not belong specifically to any of the
|
||||||
other files.
|
other files.
|
||||||
@@ -15,13 +18,29 @@ def perform_zero_padding(A, xs, ys):
|
|||||||
'''
|
'''
|
||||||
Add zero padding around the array
|
Add zero padding around the array
|
||||||
|
|
||||||
Input:
|
Input
|
||||||
|
-----
|
||||||
A - 2D-Input array
|
A - 2D-Input array
|
||||||
xs,ys - The new shape after padding.
|
xs,ys - The new shape after padding.
|
||||||
|
|
||||||
Output:
|
Output
|
||||||
|
------
|
||||||
- Array with the new padded zeros
|
- Array with the new padded zeros
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
A : TYPE
|
||||||
|
Description
|
||||||
|
xs : TYPE
|
||||||
|
Description
|
||||||
|
ys : TYPE
|
||||||
|
Description
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
TYPE
|
||||||
|
Description
|
||||||
|
|
||||||
'''
|
'''
|
||||||
assert A.shape[0] <= xs and A.shape[1] <= ys, 'New size is smaller than array size.'
|
assert A.shape[0] <= xs and A.shape[1] <= ys, 'New size is smaller than array size.'
|
||||||
x_margin = int((xs - A.shape[0])/2)
|
x_margin = int((xs - A.shape[0])/2)
|
||||||
@@ -34,6 +53,18 @@ def find_nearest(array, value):
|
|||||||
For a value it finds the nearest element in an array
|
For a value it finds the nearest element in an array
|
||||||
Returns the index of that element in the original
|
Returns the index of that element in the original
|
||||||
array.
|
array.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
array : TYPE
|
||||||
|
Description
|
||||||
|
value : TYPE
|
||||||
|
Description
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
TYPE
|
||||||
|
Description
|
||||||
'''
|
'''
|
||||||
array = np.asarray(array)
|
array = np.asarray(array)
|
||||||
diff = (np.abs(array - value)).argmin()
|
diff = (np.abs(array - value)).argmin()
|
||||||
@@ -44,6 +75,16 @@ def find_nearest(array, value):
|
|||||||
def find_maximum(array):
|
def find_maximum(array):
|
||||||
'''
|
'''
|
||||||
Finds the index of the maximum of the given array
|
Finds the index of the maximum of the given array
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
array : TYPE
|
||||||
|
Description
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
TYPE
|
||||||
|
Description
|
||||||
'''
|
'''
|
||||||
idx = np.unravel_index(array.argmax(), array.shape)
|
idx = np.unravel_index(array.argmax(), array.shape)
|
||||||
return idx
|
return idx
|
||||||
@@ -51,6 +92,16 @@ def find_maximum(array):
|
|||||||
def find_pixel_scale(x):
|
def find_pixel_scale(x):
|
||||||
'''
|
'''
|
||||||
Calculates the pixel size from the supplied array.
|
Calculates the pixel size from the supplied array.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
x : TYPE
|
||||||
|
Description
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
TYPE
|
||||||
|
Description
|
||||||
'''
|
'''
|
||||||
_dpix = np.mean(np.diff(x.real))
|
_dpix = np.mean(np.diff(x.real))
|
||||||
if _dpix < 1e-99:
|
if _dpix < 1e-99:
|
||||||
@@ -61,6 +112,20 @@ def find_pixel_scale(x):
|
|||||||
def select_subsection(x, y , outputCoordinates):
|
def select_subsection(x, y , outputCoordinates):
|
||||||
'''
|
'''
|
||||||
Returns the indices of a subsection of an x,y meshgrid
|
Returns the indices of a subsection of an x,y meshgrid
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
x : TYPE
|
||||||
|
Description
|
||||||
|
y : TYPE
|
||||||
|
Description
|
||||||
|
outputCoordinates : TYPE
|
||||||
|
Description
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
TYPE
|
||||||
|
Description
|
||||||
'''
|
'''
|
||||||
select_1 = find_nearest(x, outputCoordinates[0])[1]
|
select_1 = find_nearest(x, outputCoordinates[0])[1]
|
||||||
select_2 = find_nearest(x, outputCoordinates[1])[1]
|
select_2 = find_nearest(x, outputCoordinates[1])[1]
|
||||||
@@ -75,6 +140,22 @@ def perform_extrapolation(x, y, n, m):
|
|||||||
shape n,m
|
shape n,m
|
||||||
|
|
||||||
Returns the new extrapolated x,y meshgrid
|
Returns the new extrapolated x,y meshgrid
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
x : TYPE
|
||||||
|
Description
|
||||||
|
y : TYPE
|
||||||
|
Description
|
||||||
|
n : TYPE
|
||||||
|
Description
|
||||||
|
m : TYPE
|
||||||
|
Description
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
TYPE
|
||||||
|
Description
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Determine properties of x,y meshgrid
|
# Determine properties of x,y meshgrid
|
||||||
@@ -100,6 +181,22 @@ def plot_results(E, x, y, logscale=False, fig_size=(8,3), grid=False, show=True,
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
E : TYPE
|
||||||
|
Description
|
||||||
|
x : TYPE
|
||||||
|
Description
|
||||||
|
y : TYPE
|
||||||
|
Description
|
||||||
|
logscale : bool, optional
|
||||||
|
Description
|
||||||
|
fig_size : tuple, optional
|
||||||
|
Description
|
||||||
|
grid : bool, optional
|
||||||
|
Description
|
||||||
|
show : bool, optional
|
||||||
|
Description
|
||||||
|
colormap : str, optional
|
||||||
|
Description
|
||||||
E - 2D Array
|
E - 2D Array
|
||||||
Amplitude or intensity of the field to be shown.
|
Amplitude or intensity of the field to be shown.
|
||||||
x - Array
|
x - Array
|
||||||
@@ -160,6 +257,24 @@ def plot_real_valued_results(E, x, y, logscale=False, fig_size=(8,8), grid=False
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
E : TYPE
|
||||||
|
Description
|
||||||
|
x : TYPE
|
||||||
|
Description
|
||||||
|
y : TYPE
|
||||||
|
Description
|
||||||
|
logscale : bool, optional
|
||||||
|
Description
|
||||||
|
fig_size : tuple, optional
|
||||||
|
Description
|
||||||
|
grid : bool, optional
|
||||||
|
Description
|
||||||
|
show : bool, optional
|
||||||
|
Description
|
||||||
|
colormap : str, optional
|
||||||
|
Description
|
||||||
|
labeltext : None, optional
|
||||||
|
Description
|
||||||
E - 2D Array
|
E - 2D Array
|
||||||
Amplitude or intensity of the field to be shown.
|
Amplitude or intensity of the field to be shown.
|
||||||
x - Array
|
x - Array
|
||||||
@@ -210,6 +325,13 @@ def save_variable(filename, variable):
|
|||||||
'''
|
'''
|
||||||
Dumps the given variable to a binary pickle file
|
Dumps the given variable to a binary pickle file
|
||||||
for later use.
|
for later use.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
filename : TYPE
|
||||||
|
Description
|
||||||
|
variable : TYPE
|
||||||
|
Description
|
||||||
'''
|
'''
|
||||||
with open(filename, 'wb') as f:
|
with open(filename, 'wb') as f:
|
||||||
pickle.dump(variable, f, protocol=-1 )
|
pickle.dump(variable, f, protocol=-1 )
|
||||||
@@ -218,6 +340,16 @@ def save_variable(filename, variable):
|
|||||||
def load_variable(filename):
|
def load_variable(filename):
|
||||||
'''
|
'''
|
||||||
Loads a binary pickle file for use.
|
Loads a binary pickle file for use.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
filename : TYPE
|
||||||
|
Description
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
TYPE
|
||||||
|
Description
|
||||||
'''
|
'''
|
||||||
with open(filename, 'rb') as f:
|
with open(filename, 'rb') as f:
|
||||||
variable = pickle.load(f)
|
variable = pickle.load(f)
|
||||||
@@ -415,3 +547,58 @@ def get_free_space_propagation_rtm(x_in, y_in, theta_x_in, theta_y_in, distance)
|
|||||||
theta_x_out = theta_x_in
|
theta_x_out = theta_x_in
|
||||||
theta_y_out = theta_y_in
|
theta_y_out = theta_y_in
|
||||||
return x_out, y_out, theta_x_out, theta_y_out
|
return x_out, y_out, theta_x_out, theta_y_out
|
||||||
|
|
||||||
|
|
||||||
|
def fourier_series(x, y, c, Px=30, Py=30, xs=10, ys=10):
|
||||||
|
'''
|
||||||
|
Calculates the 2D continous Fourier Series for a set of
|
||||||
|
coefficients. This allows for interpolation on a random
|
||||||
|
phase field without artefacts (in theory...).
|
||||||
|
It is however, really quite slow for large arrays.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
x : meshgrid array
|
||||||
|
x-coordinates of the 2D array of interest
|
||||||
|
y : meshgrid array
|
||||||
|
y-coordinates of the 2D array of interest
|
||||||
|
c : 2D array
|
||||||
|
coefficients of the Fourier Series
|
||||||
|
Px : int, optional
|
||||||
|
Period length in x
|
||||||
|
Py : int, optional
|
||||||
|
Period length in y
|
||||||
|
xs : int, optional
|
||||||
|
Shift of the symmetry point x
|
||||||
|
ys : int, optional
|
||||||
|
Shift of the symmetry point in y
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
array
|
||||||
|
2D array of the Fourier Series
|
||||||
|
'''
|
||||||
|
# Shift the coordinates to remove the symmetry point
|
||||||
|
# from the output field.
|
||||||
|
xpos = x + np.sqrt(2)*xs
|
||||||
|
ypos = y + np.sqrt(2)*ys
|
||||||
|
normf = np.sum(c)
|
||||||
|
|
||||||
|
# Preparation for the calculation, to prevent doing
|
||||||
|
# the same thing over and over again.
|
||||||
|
xt = 2*np.pi*xpos/Px
|
||||||
|
yt = 2*np.pi*ypos/Py
|
||||||
|
# Doing the calculation using numba
|
||||||
|
fout = numba_fourier_series(c, xt, yt)
|
||||||
|
return fout/normf
|
||||||
|
|
||||||
|
@njit
|
||||||
|
def numba_fourier_series(c, xt, yt):
|
||||||
|
cs0, cs1 = c.shape
|
||||||
|
fout = np.zeros(xt.shape, dtype=np.float64)
|
||||||
|
for j in range(cs1):
|
||||||
|
for i in range(cs0):
|
||||||
|
v = c[i,j] * np.exp(1j * (i * xt + j * yt))
|
||||||
|
fout += v.real
|
||||||
|
return fout
|
||||||
|
|
||||||
@@ -475,16 +475,15 @@ class OpticalSurface:
|
|||||||
wfeMap = interp2d(ximg[0,:], yimg[:,0], self.sag, kind=kind, **kwargs)
|
wfeMap = interp2d(ximg[0,:], yimg[:,0], self.sag, kind=kind, **kwargs)
|
||||||
wavefrontErrorMap = wfeMap(x[0,:].real, y[:,0].real)
|
wavefrontErrorMap = wfeMap(x[0,:].real, y[:,0].real)
|
||||||
_t_l *= np.exp(1j * _k * wavefrontErrorMap )
|
_t_l *= np.exp(1j * _k * wavefrontErrorMap )
|
||||||
elif ip_type == 'phase':
|
elif ip_type in ['phase', 'fourier_series']:
|
||||||
try:
|
try:
|
||||||
xy = deepcopy((x,y))
|
xy = deepcopy((x,y))
|
||||||
xy_img = deepcopy(self.sag_coordinates)
|
xy_img = deepcopy(self.sag_coordinates)
|
||||||
wavefrontErrorMap = self.wfe.generate_height_map_window(
|
wavefrontErrorMap = self.wfe.generate_height_map_window(
|
||||||
xy, xy_img, ip_type='phase', kind=kind)
|
xy, xy_img, ip_type=ip_type, kind=kind)
|
||||||
_t_l *= np.exp(1j * _k * wavefrontErrorMap )
|
_t_l *= np.exp(1j * _k * wavefrontErrorMap )
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
print('No WavefrontError object detected. Continuing without!')
|
print('No WavefrontError object detected. Continuing without!')
|
||||||
|
|
||||||
if self.mask is not None:
|
if self.mask is not None:
|
||||||
_t_l *= self.mask
|
_t_l *= self.mask
|
||||||
return _t_l
|
return _t_l
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import types
|
|||||||
from math import ceil
|
from math import ceil
|
||||||
from scipy.special import factorial, j1
|
from scipy.special import factorial, j1
|
||||||
from scipy import interpolate
|
from scipy import interpolate
|
||||||
|
from .misc import fourier_series
|
||||||
|
|
||||||
class WavefrontError:
|
class WavefrontError:
|
||||||
'''
|
'''
|
||||||
@@ -277,7 +278,7 @@ class WavefrontError:
|
|||||||
return _phaseAngle
|
return _phaseAngle
|
||||||
|
|
||||||
|
|
||||||
def generate_height_map(self, s0, p, rho_c, addToData=False):
|
def generate_height_map(self, s0, p, rho_c, addToData=False,):
|
||||||
'''
|
'''
|
||||||
This function generates a surface height distribution based
|
This function generates a surface height distribution based
|
||||||
on a Lorentzian PSD profile. Following the paper by E. Sidick (2009).
|
on a Lorentzian PSD profile. Following the paper by E. Sidick (2009).
|
||||||
@@ -289,6 +290,11 @@ class WavefrontError:
|
|||||||
_dx = 1 / self.m
|
_dx = 1 / self.m
|
||||||
_dy = 1 / self.n
|
_dy = 1 / self.n
|
||||||
_A = (self.m * _dx) * (self.n * _dy)
|
_A = (self.m * _dx) * (self.n * _dy)
|
||||||
|
try:
|
||||||
|
_phase = self.phase
|
||||||
|
print('Phase Attribute present!')
|
||||||
|
except AttributeError:
|
||||||
|
|
||||||
_phase = np.random.uniform(0,1,(self.n,self.m))
|
_phase = np.random.uniform(0,1,(self.n,self.m))
|
||||||
self.phase = _phase
|
self.phase = _phase
|
||||||
|
|
||||||
@@ -327,12 +333,15 @@ class WavefrontError:
|
|||||||
xy - tuple containing the x and y coordinates of the small window
|
xy - tuple containing the x and y coordinates of the small window
|
||||||
xy_img - tuple containing the x and y coordinates of the full plane
|
xy_img - tuple containing the x and y coordinates of the full plane
|
||||||
to which the wfe is applied.
|
to which the wfe is applied.
|
||||||
ip_type - 'phase' or 'surface'
|
ip_type - 'phase' or 'surface' or 'fourier_series'
|
||||||
Defines what method to use to obtain the interpolated surface
|
Defines what method to use to obtain the interpolated surface
|
||||||
height map. 'surface' does a normal interpolation on the height
|
height map. 'surface' does a normal interpolation on the height
|
||||||
map. This does not conserve the WFE rms value. Then, 'phase'
|
map. This does not conserve the WFE rms value. Then, 'phase'
|
||||||
interpolates on the phase information in the PSD algorithm. This
|
interpolates on the phase information in the PSD algorithm. This
|
||||||
does conserve the WFE rms within the window.
|
does conserve the WFE rms within the window.
|
||||||
|
The last option, 'fourier_series' is very slow, but does provide
|
||||||
|
an analytical and continous solution that does not rely on
|
||||||
|
interpolation.
|
||||||
'''
|
'''
|
||||||
# normalise the coordinates to -1 to 1
|
# normalise the coordinates to -1 to 1
|
||||||
ximg, yimg = xy_img
|
ximg, yimg = xy_img
|
||||||
@@ -376,15 +385,48 @@ class WavefrontError:
|
|||||||
ptvw = np.abs(np.max(_hMapw.real)) + np.abs(np.min(_hMapw.real))
|
ptvw = np.abs(np.max(_hMapw.real)) + np.abs(np.min(_hMapw.real))
|
||||||
|
|
||||||
elif ip_type == 'surface':
|
elif ip_type == 'surface':
|
||||||
print('Hello there!')
|
|
||||||
assert hasattr(self, 'data'), 'No wfe data available to interpolate on!'
|
assert hasattr(self, 'data'), 'No wfe data available to interpolate on!'
|
||||||
try:
|
try:
|
||||||
_hMapw = self.wfe_ip(x[0,:], y[:,0])
|
_hMapw = self.wfe_ip(x[0,:], y[:,0])
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
print('Hello there 2!')
|
|
||||||
self.wfe_ip = interpolate.interp2d(ximg[0,:], yimg[:,0], self.data, kind=kind)
|
self.wfe_ip = interpolate.interp2d(ximg[0,:], yimg[:,0], self.data, kind=kind)
|
||||||
_hMapw = self.wfe_ip(x[0,:], y[:,0])
|
_hMapw = self.wfe_ip(x[0,:], y[:,0])
|
||||||
|
|
||||||
|
elif ip_type == 'fourier_series':
|
||||||
|
# Check if the coefficients are present
|
||||||
|
assert hasattr(self, 'coefficients'), 'No coefficients for the Fourier Series present!'
|
||||||
|
|
||||||
|
# Reinterpreting the coordinates, because they do not need to be scaled here
|
||||||
|
x, y = xy
|
||||||
|
x, y = x.real, y.real
|
||||||
|
|
||||||
|
# Calculation of the necessary constants
|
||||||
|
_dx = 1 / self.m
|
||||||
|
_dy = 1 / self.n
|
||||||
|
_A = (self.m * _dx) * (self.n * _dy)
|
||||||
|
|
||||||
|
# Generating the array at coordinates x, y
|
||||||
|
print('Applying the Fourier series. This might take a while...')
|
||||||
|
_phase_window = fourier_series(x, y, self.coefficients)
|
||||||
|
print('Fourier series calculated!')
|
||||||
|
|
||||||
|
# Generating the surface
|
||||||
|
_PSDw, _rho_mn_listw = self.PSD2D, self.rho_mn_list
|
||||||
|
_phiMap_window = self.phase_map(_phase_window)
|
||||||
|
_PSDw = np.fft.ifftshift(_PSDw)
|
||||||
|
|
||||||
|
# Doing the fourier transform of the window
|
||||||
|
_inw = pyfftw.empty_aligned((self.n,self.m), dtype='complex128')
|
||||||
|
_inw[:] = np.exp( 1j * _phiMap_window) * np.sqrt(_A * np.abs(_PSDw))
|
||||||
|
_outw = pyfftw.empty_aligned((self.n,self.m), dtype='complex128')
|
||||||
|
_FFTW_Objw = pyfftw.FFTW( _inw, _outw, axes=(0,1), direction='FFTW_BACKWARD', threads=6, flags=('FFTW_ESTIMATE',))
|
||||||
|
_FFTW_Objw()
|
||||||
|
|
||||||
|
_hMapw = 1 / ( _dx * _dy ) * _outw
|
||||||
|
rmsw = np.sqrt(np.mean(np.asarray(_hMapw.real)**2))
|
||||||
|
ptvw = np.abs(np.max(_hMapw.real)) + np.abs(np.min(_hMapw.real))
|
||||||
|
|
||||||
|
|
||||||
if not addToData:
|
if not addToData:
|
||||||
self.data_window = _hMapw.real
|
self.data_window = _hMapw.real
|
||||||
else:
|
else:
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,86 @@
|
|||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import sys
|
||||||
|
# sys.path.insert(0, '/Users/joost/Dropbox/Werk/PhD/Analyses/Python/Analytical/Fourier Optics')
|
||||||
|
# sys.path.insert(0, '/home/joost/Dropbox/Werk/PhD/Analyses/Python/Analytical/Fourier Optics')
|
||||||
|
sys.path.insert(0, '/Users/joost/Dropbox/Werk/PhD/Documents/Published/FourierOptics GitHub release/')
|
||||||
|
from fourierOptics import *
|
||||||
|
from pdb import set_trace
|
||||||
|
|
||||||
|
'''
|
||||||
|
@Author: Joost van den Born
|
||||||
|
@Date: 14 July, 2022
|
||||||
|
@Description: I use this script to create a large array (1001x1001 and 3001x3001)
|
||||||
|
that can be used for the phase screen in the WFE production.
|
||||||
|
Because it takes very long to generate these at this high resolution,
|
||||||
|
we will need to save them to a pickle file.
|
||||||
|
|
||||||
|
What is saved:
|
||||||
|
The array of coefficients
|
||||||
|
The array of the full phase field
|
||||||
|
|
||||||
|
To Do:
|
||||||
|
- Normalize/Scale the amplitude in an appropriate manner.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# plt.rc('text', usetex=True)
|
||||||
|
# plt.rc('font', family='serif')
|
||||||
|
import time
|
||||||
|
# Setup of simulation
|
||||||
|
l = 1.49e-3
|
||||||
|
# mcd = ParaxialMICADO(n=1001, m=1001, dpix=160)
|
||||||
|
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50)
|
||||||
|
# mcd.plot_ray_trace()
|
||||||
|
wfe = WavefrontError(mcd.n, mcd.m)
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------------------------
|
||||||
|
####### GENERATING THE PHASE WITH A FOURIER SERIES ######
|
||||||
|
# -------------------------------------------------------
|
||||||
|
# Get x3 and y3 (the coordinates to apply the ADC WFE to):
|
||||||
|
# The focal plane area is about 200x200 mm, so we apply the wavefront error to an area
|
||||||
|
# of 200x200 mm.
|
||||||
|
xfp, yfp = np.meshgrid(np.linspace(-150, 150, mcd.n), np.linspace(-150, 150, mcd.m))
|
||||||
|
# np.random.seed(2183)
|
||||||
|
# coeff = np.random.uniform(-1,1,(int(mcd.n/3),int(mcd.m/3)))
|
||||||
|
np.random.seed(2183)
|
||||||
|
coeff = np.random.uniform(-1,1,(101,101))
|
||||||
|
|
||||||
|
if False:
|
||||||
|
print('Going in...')
|
||||||
|
s1 = time.time()
|
||||||
|
fs_array = fourier_series(xfp, yfp, coeff, Px=300, Py=300, xs=150, ys=150)
|
||||||
|
s2 = time.time()
|
||||||
|
print('Finished!')
|
||||||
|
print('That took me {:.4f} s!'.format(s2-s1) )
|
||||||
|
save_variable('wfe_fp_phase_array_coefficients_{}_{}.pkl'.format(mcd.n, mcd.m), coeff)
|
||||||
|
save_variable('wfe_fp_phase_array_{}_{}.pkl'.format(mcd.n, mcd.m), fs_array)
|
||||||
|
|
||||||
|
# -------------------------------------------------------
|
||||||
|
# -------------------------------------------------------
|
||||||
|
# -------------------------------------------------------
|
||||||
|
|
||||||
|
if True:
|
||||||
|
# coeff = load_variable('wfe_fp_phase_array_coefficients_{}_{}.pkl'.format(mcd.n, mcd.m))
|
||||||
|
fs_array = load_variable('wfe_fp_phase_array_{}_{}.pkl'.format(mcd.n, mcd.m))
|
||||||
|
|
||||||
|
wfe.phase = fs_array
|
||||||
|
surf = wfe.generate_height_map(50e-6, 2, 1)
|
||||||
|
rms = np.sqrt(np.mean(surf**2))
|
||||||
|
print('RMS: {}'.format(rms))
|
||||||
|
|
||||||
|
|
||||||
|
plt.figure()
|
||||||
|
plt.imshow(fs_array, cmap='jet', extent=[xfp.min(), xfp.max(), yfp.min(), yfp.max()], origin='lower')
|
||||||
|
plt.colorbar()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
plt.figure()
|
||||||
|
plt.imshow(surf, cmap='jet', extent=[xfp.min(), xfp.max(), yfp.min(), yfp.max()], origin='lower')
|
||||||
|
plt.colorbar()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
@@ -16,14 +16,14 @@ from pdb import set_trace
|
|||||||
Script made for the SPIE manuscript.
|
Script made for the SPIE manuscript.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def plot_distortions():
|
def plot_distortions(xe, ye, xf, yf):
|
||||||
# Coordinates without WFEs
|
# Coordinates without WFEs
|
||||||
xe = load_variable('../data/GD_IFP_obscured_PSF_xcentroid_expected_zern.pkl')
|
# xe = load_variable('../data/GD_IFP_zoom93_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
ye = load_variable('../data/GD_IFP_obscured_PSF_ycentroid_expected_zern.pkl')
|
# ye = load_variable('../data/GD_IFP_zoom93_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
|
||||||
# Coordinates with WFEs
|
# # Coordinates with WFEs
|
||||||
xf = load_variable('../data/GD_IFP_obscured_PSF_xcentroid_found_with_wfe_airy_zern.pkl')
|
# xf = load_variable('../data/GD_IFP_zoom93_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
yf = load_variable('../data/GD_IFP_obscured_PSF_ycentroid_found_with_wfe_airy_zern.pkl')
|
# yf = load_variable('../data/GD_IFP_zoom93_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50, l=1.49e-3)
|
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50, l=1.49e-3)
|
||||||
|
|
||||||
@@ -53,8 +53,8 @@ def plot_distortions():
|
|||||||
ax.set_xlabel('x (mm)')
|
ax.set_xlabel('x (mm)')
|
||||||
ax.set_ylabel('y (mm)')
|
ax.set_ylabel('y (mm)')
|
||||||
fig.colorbar(im, ax=ax, label='PSF centroid shift ($\\mu$as)')
|
fig.colorbar(im, ax=ax, label='PSF centroid shift ($\\mu$as)')
|
||||||
plt.savefig('../figures/UPDATED_GD_focal_plane_zern.pdf', bbox_inches='tight', transparent=True)
|
# plt.savefig('../figures/UPDATED_GD_zoom93_focal_plane_zern.pdf', bbox_inches='tight', transparent=True)
|
||||||
plt.savefig('../figures/UPDATED_GD_focal_plane_zern.png', bbox_inches='tight', transparent=True)
|
# plt.savefig('../figures/UPDATED_GD_zoom93_focal_plane_zern.png', bbox_inches='tight', transparent=True)
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
@@ -62,11 +62,10 @@ def plot_distortions():
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# plt.rc('text', usetex=True)
|
# plt.rc('text', usetex=True)
|
||||||
# plt.rc('font', family='serif')
|
# plt.rc('font', family='serif')
|
||||||
|
|
||||||
# Setup of simulation
|
# Setup of simulation
|
||||||
l = 1.49e-3
|
l = 1.49e-3
|
||||||
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50)
|
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50)
|
||||||
# mcd.plot_ray_trace()
|
print(mcd.platescale)
|
||||||
wfe = WavefrontError(mcd.n, mcd.m)
|
wfe = WavefrontError(mcd.n, mcd.m)
|
||||||
|
|
||||||
# Get x3 and y3 (the coordinates to apply the ADC WFE to):
|
# Get x3 and y3 (the coordinates to apply the ADC WFE to):
|
||||||
@@ -80,16 +79,40 @@ if __name__ == '__main__':
|
|||||||
print('\nSetting the wavefront errors...')
|
print('\nSetting the wavefront errors...')
|
||||||
wfe_fp = WavefrontError(mcd.n,mcd.m)
|
wfe_fp = WavefrontError(mcd.n,mcd.m)
|
||||||
wfe_rms = 50e-6
|
wfe_rms = 50e-6
|
||||||
|
|
||||||
|
psdWFE = True
|
||||||
|
zernikeWFE = False
|
||||||
|
|
||||||
|
if psdWFE:
|
||||||
#PSD Wavefront error
|
#PSD Wavefront error
|
||||||
# surface_map_fp = wfe_fp.generate_height_map(wfe_rms, 2, 1)
|
# surface_map_fp = wfe_fp.generate_height_map(wfe_rms, 2, 1)
|
||||||
# plot_real_valued_results(surface_map_fp*1e6, xfp, yfp, logscale=False, fig_size=(8,6.4), grid=False, show=True,
|
# plot_real_valued_results(surface_map_fp*1e6, xfp, yfp, logscale=False, fig_size=(8,6.4), grid=False, show=True,
|
||||||
# colormap='jet', labeltext='Surface height (nm)')
|
# colormap='jet', labeltext='Surface height (nm)')
|
||||||
# save_variable('../data/MCD_IFP_wfe_object_PSD_50nm.pkl', wfe_fp)
|
# save_variable('../data/MCD_IFP_wfe_object_PSD_50nm.pkl', wfe_fp)
|
||||||
# wfe_fp = load_variable('../data/MCD_IFP_wfe_object_PSD_50nm.pkl')
|
# wfe_fp = load_variable('../data/MCD_IFP_wfe_object_PSD_50nm.pkl')
|
||||||
# surface_map_fp = wfe_fp.data
|
wfe_fp = load_variable('../data/GD Focal Plane WFEs/MCD_IFP_wfe_object_PSD_50nm.pkl')
|
||||||
|
surface_map_fp = wfe_fp.data
|
||||||
|
|
||||||
|
# from copy import deepcopy
|
||||||
|
# xy_img = deepcopy((xfp, yfp))
|
||||||
|
# x, y = np.meshgrid(np.linspace(-10, 10, mcd.n), np.linspace(-10, 10, mcd.m))
|
||||||
|
# xy = deepcopy((x,y))
|
||||||
|
# zoom_map = wfe_fp.generate_height_map_window(
|
||||||
|
# xy, xy_img, ip_type='phase')
|
||||||
|
|
||||||
|
|
||||||
|
# plt.figure()
|
||||||
|
# plt.grid()
|
||||||
|
# plt.plot(1e3*x[1500,:], 1e6*zoom_map[1500,:], '-')
|
||||||
|
# # plt.imshow(1e6*zoom_map, cmap='jet', extent=[x.min(), x.max(), y.min(), y.max()],
|
||||||
|
# # origin='lower', vmin=-150, vmax=150)
|
||||||
|
# plt.xlabel('x (μm)')
|
||||||
|
# plt.ylabel('surface heigth (nm)')
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
if zernikeWFE:
|
||||||
# Zernike wavefront error
|
# Zernike wavefront error
|
||||||
# We re0se the ADC_surface classes because it can be applicable to any surface, if used properly
|
# We reuse the ADC_surface classes because it can be applicable to any surface, if used properly
|
||||||
ifp_wfe = ADC_surfaces(xfp, yfp, clearAperture=300)
|
ifp_wfe = ADC_surfaces(xfp, yfp, clearAperture=300)
|
||||||
ifp_wfe.generate_ADC_wfe(zernRMS=wfe_rms, psdRMS=0.)
|
ifp_wfe.generate_ADC_wfe(zernRMS=wfe_rms, psdRMS=0.)
|
||||||
mask = np.sqrt(ifp_wfe.xz**2 + ifp_wfe.yz**2) > 1
|
mask = np.sqrt(ifp_wfe.xz**2 + ifp_wfe.yz**2) > 1
|
||||||
@@ -100,12 +123,45 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
# surface_map_fp = surf_ifp
|
# surface_map_fp = surf_ifp
|
||||||
# wfe_fp.data = surf_ifp
|
# wfe_fp.data = surf_ifp
|
||||||
wfe_fp = load_variable('../data/MCD_IFP_wfe_object_zern_50nm.pkl')
|
# wfe_fp = load_variable('../data/GD Focal Plane WFEs/MCD_IFP_wfe_object_zern_50nm.pkl')
|
||||||
surface_map_fp = wfe_fp.data
|
surface_map_fp = wfe_fp.data
|
||||||
# save_variable('../data/MCD_IFP_wfe_object_zern_50nm.pkl', wfe_fp)
|
# save_variable('../data/MCD_IFP_wfe_object_zern_50nm.pkl', wfe_fp)
|
||||||
# figp1, axp1 = plot_real_valued_results(surface_map_fp*1e6, xfp, yfp,
|
# figp1, axp1 = plot_real_valued_results(surface_map_fp*1e6, xfp, yfp,
|
||||||
# colormap='jet', labeltext='Surface height (nm)', fig_size=None, show=True)
|
# colormap='jet', labeltext='Surface height (nm)', fig_size=None, show=True)
|
||||||
plt.show()
|
# plt.show()
|
||||||
|
# plt.close()
|
||||||
|
|
||||||
|
|
||||||
|
# List of performed simulations
|
||||||
|
# Defined by PSD
|
||||||
|
## GD_IFP : -1:1
|
||||||
|
## GD_IFP_zoom : -1/11 :1/11
|
||||||
|
## GD_IFP_zoom2 : -.5/11:.5/11
|
||||||
|
## GD_IFP_zoom3 : -.1/11:.1/11
|
||||||
|
## GD_IFP_zoom7 : -.02/11:.02/11, surface interpolation
|
||||||
|
## GD_IFP_zoom8 : -.05/11:.05/11, surface interpolation
|
||||||
|
## GD_IFP_zoom9 : -.01/11:.01/11, surface interpolation
|
||||||
|
## GD_IFP_zoom91 : -.01/11:.01/11 but hx and hy shifted to an area near the corner of the image, where distortion is supposed to be large
|
||||||
|
## GD_IFP_zoom92 : -.01/11:.01/11, phase interpolation
|
||||||
|
## GD_IFP_zoom93 : -.004/11:.004/11, phase interpolation
|
||||||
|
# (implemented)IDEA: Automate it, let it run all simulations for the lower left corner. Take multiples of 11 for the field points
|
||||||
|
# i.e. 1/11, 1/11**2, 1/11**3, 1/11**4
|
||||||
|
# GD_IFP_zoom94 : - 1/11:1/11, phase interpolation, with shift to left bottom corner
|
||||||
|
# GD_IFP_zoom95 : - 1/11**2:1/11**2, phase interpolation, with shift to left bottom corner
|
||||||
|
# GD_IFP_zoom96 : - 1/11**3:1/11**3, phase interpolation, with shift to left bottom corner
|
||||||
|
# GD_IFP_zoom97 : - 1/11:1/11, phase interpolation, center of the field
|
||||||
|
# GD_IFP_zoom98 : - 1/11**2:1/11**2, phase interpolation, center of the field
|
||||||
|
# GD_IFP_zoom99 : - 1/11**3:1/11**3, phase interpolation, center of the field
|
||||||
|
# GD_IFP_zoom100 : - 1/11**4:1/11**4, phase interpolation, center of the field
|
||||||
|
# GD_IFP_zoom101 : - 1/11**4:1/11**4, phase interpolation, center of the field, with shift to left bottom corner
|
||||||
|
|
||||||
|
# Defined by zernikes
|
||||||
|
## GD_IFP_obscured_PSF_xcentroid_expected_zern : 50 nm rms 19 zernike modes : -1 : 1
|
||||||
|
## To do; check PSF shape at center field with zern wfe
|
||||||
|
## To do; check interpolated WFE at any zoomed in field point.
|
||||||
|
## GD_IFP_zoom4 : -.02/11:.02/11 (actually zernike WFE!), surface interpolation --> CONTINUOUS :D
|
||||||
|
## GD_IFP_zoom5 : -.05/11:.05/11 (actually zernike WFE!), surface interpolation --> CONTINUOUS :D
|
||||||
|
## GD_IFP_zoom6 : -.05/11:.05/11, surface interpolation, but hx and hy shifted to an area near the corner of the image (actually zern!)
|
||||||
|
|
||||||
|
|
||||||
Elist, Eplist = [], []
|
Elist, Eplist = [], []
|
||||||
@@ -117,23 +173,26 @@ if __name__ == '__main__':
|
|||||||
# Set field points
|
# Set field points
|
||||||
hxList, hyList = np.mgrid[-1:1:11j,-1:1:11j]-(1/300)
|
hxList, hyList = np.mgrid[-1:1:11j,-1:1:11j]-(1/300)
|
||||||
# hxList, hyList = np.mgrid[-.1/11:.1/11:11j,-.1/11:.1/11:11j]-(1/300) # Zoomed in to central area
|
# hxList, hyList = np.mgrid[-.1/11:.1/11:11j,-.1/11:.1/11:11j]-(1/300) # Zoomed in to central area
|
||||||
|
# hxList, hyList = np.mgrid[-.004/11:.004/11:11j,-.004/11:.004/11:11j]-(1/300) # Zoomed in to central area
|
||||||
hxList = hxList.flatten()
|
hxList = hxList.flatten()
|
||||||
hyList = hyList.flatten()
|
hyList = hyList.flatten()
|
||||||
|
|
||||||
# List of performed simulations
|
# Zooming in around -84mm by -84mm on the image plane
|
||||||
# Defined by PSD
|
ihx = hxList[108]
|
||||||
## GD_IFP : -1:1
|
ihy = hyList[108]
|
||||||
## GD_IFP_zoom : -1/11 :1/11
|
|
||||||
## GD_IFP_zoom2 : -.5/11:.5/11
|
|
||||||
## GD_IFP_zoom3 : -.1/11:.1/11
|
|
||||||
|
|
||||||
# Defined by zernikes
|
for p in [4]:
|
||||||
## GD_IFP_obscured_PSF_xcentroid_expected_zern : 50 nm rms 19 zernike modes : -1 : 1
|
x_expected_list, y_expected_list = [], []
|
||||||
## To do; check PSF shape at center field with zern wfe
|
x_centroid_list, y_centroid_list = [], []
|
||||||
## To do; check interpolated WFE at any zoomed in field point.
|
|
||||||
|
hxList, hyList = np.mgrid[ihx-1/11**p:ihx+1/11**p:11j,
|
||||||
|
ihy-1/11**p:ihy+1/11**p:11j]-(1/300)
|
||||||
|
hxList = hxList.flatten()
|
||||||
|
hyList = hyList.flatten()
|
||||||
|
|
||||||
# Propagate through the field positions without any WFEs
|
# Propagate through the field positions without any WFEs
|
||||||
for i in range(len(hxList)):
|
for i in range(len(hxList)):
|
||||||
|
print('Field point #: {}/{}'.format(i+1, len(hxList)))
|
||||||
hx = hxList[i]
|
hx = hxList[i]
|
||||||
hy = hyList[i]
|
hy = hyList[i]
|
||||||
print('hx: {} - hy: {}'.format(hx,hy) )
|
print('hx: {} - hy: {}'.format(hx,hy) )
|
||||||
@@ -193,9 +252,9 @@ if __name__ == '__main__':
|
|||||||
y_expected = np.asarray(y_expected_list).reshape(shape)#.T
|
y_expected = np.asarray(y_expected_list).reshape(shape)#.T
|
||||||
|
|
||||||
# Saving the arrays
|
# Saving the arrays
|
||||||
save_variable('../data/GD_IFP_obscured_PSF_xcentroid_expected_zern.pkl', x_expected)
|
zoom_value = 97 + p
|
||||||
save_variable('../data/GD_IFP_obscured_PSF_ycentroid_expected_zern.pkl', y_expected)
|
save_variable('../data/GD_IFP_zoom{:.0f}_obscured_PSF_xcentroid_expected_zern_psd.pkl'.format(zoom_value), x_expected)
|
||||||
|
save_variable('../data/GD_IFP_zoom{:.0f}_obscured_PSF_ycentroid_expected_zern_psd.pkl'.format(zoom_value), y_expected)
|
||||||
|
|
||||||
# Reshaping the arrays
|
# Reshaping the arrays
|
||||||
shape = (int(np.sqrt(len(x_centroid_list))), int(np.sqrt(len(x_centroid_list))))
|
shape = (int(np.sqrt(len(x_centroid_list))), int(np.sqrt(len(x_centroid_list))))
|
||||||
@@ -203,10 +262,10 @@ if __name__ == '__main__':
|
|||||||
y_centroid = np.asarray(y_centroid_list).reshape(shape)
|
y_centroid = np.asarray(y_centroid_list).reshape(shape)
|
||||||
|
|
||||||
# Saving the arrays
|
# Saving the arrays
|
||||||
save_variable('../data/GD_IFP_obscured_PSF_xcentroid_found_with_wfe_airy_zern.pkl', x_centroid)
|
save_variable('../data/GD_IFP_zoom{:.0f}_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl'.format(zoom_value), x_centroid)
|
||||||
save_variable('../data/GD_IFP_obscured_PSF_ycentroid_found_with_wfe_airy_zern.pkl', y_centroid)
|
save_variable('../data/GD_IFP_zoom{:.0f}_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl'.format(zoom_value), y_centroid)
|
||||||
|
|
||||||
plot_distortions()
|
plot_distortions(x_expected, y_expected, x_centroid, y_centroid)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
import numpy as np
|
||||||
|
import sys
|
||||||
|
# sys.path.insert(0, '/Users/joost/Dropbox/Werk/PhD/Analyses/Python/Analytical/Fourier Optics')
|
||||||
|
# sys.path.insert(0, '/home/joost/Dropbox/Werk/PhD/Analyses/Python/Analytical/Fourier Optics')
|
||||||
|
sys.path.insert(0, '/Users/joost/Dropbox/Werk/PhD/Documents/Published/FourierOptics GitHub release/')
|
||||||
|
from fourierOptics import *
|
||||||
|
from pdb import set_trace
|
||||||
|
|
||||||
|
'''
|
||||||
|
Author: Joost van den Born, PhD student at University of Groningen
|
||||||
|
Contact: born@astro.rug.nl
|
||||||
|
Description: Script to generate the geometric distortions due to WFEs
|
||||||
|
off the ADC prisms. The distortions are produced by measuring
|
||||||
|
the offset of the PSF centroid with and without WFE as a
|
||||||
|
function of field position.
|
||||||
|
Script made for the SPIE manuscript.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def plot_distortions():
|
||||||
|
# Coordinates without WFEs
|
||||||
|
xe = load_variable('../data/GD_IFP_obscured_PSF_xcentroid_expected_fs.pkl')
|
||||||
|
ye = load_variable('../data/GD_IFP_obscured_PSF_ycentroid_expected_fs.pkl')
|
||||||
|
|
||||||
|
# Coordinates with WFEs
|
||||||
|
xf = load_variable('../data/GD_IFP_obscured_PSF_xcentroid_found_with_wfe_airy_fs.pkl')
|
||||||
|
yf = load_variable('../data/GD_IFP_obscured_PSF_ycentroid_found_with_wfe_airy_fs.pkl')
|
||||||
|
|
||||||
|
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50, l=1.49e-3)
|
||||||
|
|
||||||
|
n = xe.shape[0]
|
||||||
|
X = xe.flatten()
|
||||||
|
Y = ye.flatten()
|
||||||
|
dX = xf - xe
|
||||||
|
dY = yf - ye
|
||||||
|
dx = dX.flatten()
|
||||||
|
dy = dY.flatten()
|
||||||
|
|
||||||
|
# Magnitude of the distortions
|
||||||
|
R = np.sqrt(dx**2 + dy**2) * mcd.platescale * 1e6
|
||||||
|
|
||||||
|
# Dummy figure, used for the colorbar colors in the quiver plot
|
||||||
|
im = plt.imshow(np.reshape(R, (n,n)))
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
fig = plt.figure()
|
||||||
|
ax = fig.add_subplot()
|
||||||
|
for i in range(len(xe)):
|
||||||
|
ax.plot(xe[:,i], ye[:,i], 'k-', alpha=0.2, linewidth=.5)
|
||||||
|
ax.plot(xe[i,:], ye[i,:], 'k-', alpha=0.2, linewidth=.5)
|
||||||
|
ax.quiver(X,Y,dx,dy, angles='xy', edgecolor='k', facecolor='None', linewidth=.5, units='dots')
|
||||||
|
ax.quiver(X,Y,dx,dy,R, alpha=.5, units='dots')
|
||||||
|
ax.set_aspect('equal', adjustable='box')
|
||||||
|
ax.set_xlabel('x (mm)')
|
||||||
|
ax.set_ylabel('y (mm)')
|
||||||
|
fig.colorbar(im, ax=ax, label='PSF centroid shift ($\\mu$as)')
|
||||||
|
plt.savefig('../figures/UPDATED_GD_focal_plane_fs.pdf', bbox_inches='tight', transparent=True)
|
||||||
|
plt.savefig('../figures/UPDATED_GD_focal_plane_fs.png', bbox_inches='tight', transparent=True)
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# plt.rc('text', usetex=True)
|
||||||
|
plt.rc('font', family='serif')
|
||||||
|
plt.rc('axes', labelsize='large')
|
||||||
|
|
||||||
|
|
||||||
|
# Setup of simulation
|
||||||
|
l = 1.49e-3
|
||||||
|
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50)
|
||||||
|
# mcd.plot_ray_trace()
|
||||||
|
|
||||||
|
# Get x3 and y3 (the coordinates to apply the ADC WFE to):
|
||||||
|
# The focal plane area is about 200x200 mm, so we apply the wavefront error to an area
|
||||||
|
# of 200x200 mm.
|
||||||
|
xfp, yfp = np.meshgrid(np.linspace(-150, 150, mcd.n), np.linspace(-150, 150, mcd.m))
|
||||||
|
# _, xfp, yfp = mcd.propagate(l=l,surface=1, zoom=False, show=False,
|
||||||
|
# print_progress=False)
|
||||||
|
|
||||||
|
# Generate a wavefront error for the intermediate focal plane.
|
||||||
|
print('\nSetting the wavefront errors...')
|
||||||
|
wfe_fp = WavefrontError(mcd.n,mcd.m)
|
||||||
|
wfe_rms = 15000e-6
|
||||||
|
#PSD Wavefront error
|
||||||
|
|
||||||
|
# Loading the phase generated using a Fourier Series
|
||||||
|
fs_array = load_variable('wfe_fp_phase_array_{}_{}.pkl'.format(mcd.n, mcd.m))
|
||||||
|
|
||||||
|
# Retrieving the coefficients for the Fourier series
|
||||||
|
np.random.seed(2183)
|
||||||
|
coeff = np.random.uniform(-1,1,(101,101))
|
||||||
|
wfe_fp.coefficients = coeff
|
||||||
|
fs_array = fourier_series(xfp, yfp, coeff, Px=30, Py=30, xs=10, ys=10)
|
||||||
|
|
||||||
|
# Setting the initial full window phase array to generate the full window surface height map.
|
||||||
|
wfe_fp.phase = fs_array
|
||||||
|
surface_map_fp = wfe_fp.generate_height_map(wfe_rms, 2, 1)
|
||||||
|
# plot_real_valued_results(surface_map_fp*1e6, xfp, yfp, logscale=False, fig_size=(8,6.4), grid=False, show=True,
|
||||||
|
# colormap='jet', labeltext='Surface height (nm)')
|
||||||
|
|
||||||
|
# save_variable('../data/MCD_IFP_wfe_object_PSD_50nm.pkl', wfe_fp)
|
||||||
|
# wfe_fp = load_variable('../data/MCD_IFP_wfe_object_PSD_50nm.pkl')
|
||||||
|
# surface_map_fp = wfe_fp.data
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
Elist, Eplist = [], []
|
||||||
|
xlist, ylist = [], []
|
||||||
|
xplist, yplist = [], []
|
||||||
|
x_expected_list, y_expected_list = [], []
|
||||||
|
x_centroid_list, y_centroid_list = [], []
|
||||||
|
|
||||||
|
# Set field points
|
||||||
|
hxList, hyList = np.mgrid[-1:1:11j,-1:1:11j]-(1/300)
|
||||||
|
# hxList, hyList = np.mgrid[-.1/11:.1/11:11j,-.1/11:.1/11:11j]-(1/300) # Zoomed in to central area
|
||||||
|
hxList = hxList.flatten()
|
||||||
|
hyList = hyList.flatten()
|
||||||
|
# hxList, hyList = [0.0], [0.0]
|
||||||
|
|
||||||
|
# List of performed simulations
|
||||||
|
# Defined by PSD
|
||||||
|
## GD_IFP : -1:1
|
||||||
|
## GD_IFP_zoom : -1/11 :1/11
|
||||||
|
## GD_IFP_zoom2 : -.5/11:.5/11
|
||||||
|
## GD_IFP_zoom3 : -.1/11:.1/11
|
||||||
|
|
||||||
|
# Defined by zernikes
|
||||||
|
## GD_IFP_obscured_PSF_xcentroid_expected_zern : 50 nm rms 19 zernike modes : -1 : 1
|
||||||
|
## To do; check PSF shape at center field with zern wfe
|
||||||
|
## To do; check interpolated WFE at any zoomed in field point.
|
||||||
|
|
||||||
|
# Propagate through the field positions without any WFEs
|
||||||
|
for i in range(len(hxList)):
|
||||||
|
hx = hxList[i]
|
||||||
|
hy = hyList[i]
|
||||||
|
print('Data point: i={:.0f} of i_max={:.0f}'.format(i, len(hxList)))
|
||||||
|
print('hx: {} - hy: {}'.format(hx,hy) )
|
||||||
|
|
||||||
|
# Initializing MICADO paraxial model
|
||||||
|
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50, entrance_pupil='obscured')
|
||||||
|
|
||||||
|
# Propagate through the MICADO system
|
||||||
|
E, x, y = mcd.propagate(l=l,surface=-1, zoom=False, show=False,
|
||||||
|
print_progress=False, hx=hx, hy=hy)
|
||||||
|
|
||||||
|
# Find approximation for the centroid and amplitude as a first
|
||||||
|
# guess for the Obscured Airy pattern fit.
|
||||||
|
amplitude_guess = np.max(np.abs(E))**2
|
||||||
|
xbc, ybc, _, _ = mcd.centroid_shift(method='Barycenter')
|
||||||
|
print('Barycenter guess: ', xbc, ybc)
|
||||||
|
|
||||||
|
# Do the Obscured Airy Pattern Fit for the unperturbed PSF
|
||||||
|
xe, ye, _, _ = mcd.centroid_shift(method='Obscured Airy', initialGuess=(amplitude_guess, xbc, ybc, 0.0, 0.03))
|
||||||
|
print('Airy result: ', xe, ye)
|
||||||
|
x_expected_list.append(xe)
|
||||||
|
y_expected_list.append(ye)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Load in the WFEs and set them to the corresponding ADC surfaces
|
||||||
|
print('\nSetting the wavefront errors...')
|
||||||
|
# null_wfe = np.zeros((3001,3001))
|
||||||
|
mcd.ELT_FP.add_wavefront_error(surface_map_fp, xfp, yfp, wfe=wfe_fp)
|
||||||
|
|
||||||
|
|
||||||
|
# Propagate through the MICADO system
|
||||||
|
print('Propagating with Wavefront Errors applied...')
|
||||||
|
Ep, xp, yp = mcd.propagate(l=l,surface=-1, zoom=False, show=True,
|
||||||
|
print_progress=False, hx=hx, hy=hy)
|
||||||
|
|
||||||
|
|
||||||
|
# Do the Obscured Airy Pattern Fit for the perturbed PSF
|
||||||
|
xf, yf, _, _ = mcd.centroid_shift(method='Obscured Airy', initialGuess=(amplitude_guess, xe, ye, 0.0, 0.03))
|
||||||
|
|
||||||
|
# Resulting centroid shift due to the WFE
|
||||||
|
x_centroid_list.append(xf)
|
||||||
|
y_centroid_list.append(yf)
|
||||||
|
R = np.sqrt( (xf-xe)**2 + (yf-ye)**2 ) * mcd.platescale * 1e6
|
||||||
|
print('xf: {}, yf: {}, shift (uas): {}'.format(xf,yf, R))
|
||||||
|
|
||||||
|
data_tuple = (i, hx, hy, xe, ye, xf, yf)
|
||||||
|
data_name = 'gd_point_{:03d}_hx{}_hy{}.pkl'.format(i, hx, hy)
|
||||||
|
save_variable('../data/GD_IFP_intermediate_results/{}'.format(data_name), data_tuple)
|
||||||
|
|
||||||
|
# Clear the memory by emptying the large arrays
|
||||||
|
mcd = None
|
||||||
|
wfe = None
|
||||||
|
E, x, y = None, None, None
|
||||||
|
Ep, xp, yp = None, None, None
|
||||||
|
|
||||||
|
|
||||||
|
# Reshaping the arrays
|
||||||
|
shape = (int(np.sqrt(len(x_expected_list))), int(np.sqrt(len(x_expected_list))))
|
||||||
|
x_expected = np.asarray(x_expected_list).reshape(shape)
|
||||||
|
y_expected = np.asarray(y_expected_list).reshape(shape)#.T
|
||||||
|
|
||||||
|
# Saving the arrays
|
||||||
|
save_variable('../data/GD_IFP_obscured_PSF_xcentroid_expected_fs.pkl', x_expected)
|
||||||
|
save_variable('../data/GD_IFP_obscured_PSF_ycentroid_expected_fs.pkl', y_expected)
|
||||||
|
|
||||||
|
|
||||||
|
# Reshaping the arrays
|
||||||
|
shape = (int(np.sqrt(len(x_centroid_list))), int(np.sqrt(len(x_centroid_list))))
|
||||||
|
x_centroid = np.asarray(x_centroid_list).reshape(shape)
|
||||||
|
y_centroid = np.asarray(y_centroid_list).reshape(shape)
|
||||||
|
|
||||||
|
# Saving the arrays
|
||||||
|
save_variable('../data/GD_IFP_obscured_PSF_xcentroid_found_with_wfe_airy_fs.pkl', x_centroid)
|
||||||
|
save_variable('../data/GD_IFP_obscured_PSF_ycentroid_found_with_wfe_airy_fs.pkl', y_centroid)
|
||||||
|
|
||||||
|
plot_distortions()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -91,9 +91,10 @@ def convert_detector_size(x, y, old=True):
|
|||||||
def plot_distortions(xe, ye, xp, yp, lims=False, add_detectors=True,
|
def plot_distortions(xe, ye, xp, yp, lims=False, add_detectors=True,
|
||||||
save=False, figtitle='geom_distortions',
|
save=False, figtitle='geom_distortions',
|
||||||
show=True, cmap='magma'):
|
show=True, cmap='magma'):
|
||||||
vmin, vmax = 0.1, 100
|
vmin, vmax = 0.01, 100
|
||||||
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50, l=1.49e-3)
|
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50, l=1.49e-3)
|
||||||
n = xe.shape[0]
|
n = xe.shape[0]
|
||||||
|
no_of_grids = int(n/121)
|
||||||
X = xe.flatten()
|
X = xe.flatten()
|
||||||
Y = ye.flatten()
|
Y = ye.flatten()
|
||||||
dX = xp - xe
|
dX = xp - xe
|
||||||
@@ -103,7 +104,7 @@ def plot_distortions(xe, ye, xp, yp, lims=False, add_detectors=True,
|
|||||||
|
|
||||||
# Magnitude of the distortions
|
# Magnitude of the distortions
|
||||||
R = np.sqrt(dx**2 + dy**2) * mcd.platescale * 1e6
|
R = np.sqrt(dx**2 + dy**2) * mcd.platescale * 1e6
|
||||||
print('RMS of the PSF shifts: {:.4f} μas.'.format(np.sqrt(np.mean((R)**2))))
|
print('RMS of the PSF shifts: {:.4f} μas.'.format(np.sqrt(np.mean((R[:121])**2))))
|
||||||
|
|
||||||
# Dummy figure, used for the colorbar colors in the quiver plot
|
# Dummy figure, used for the colorbar colors in the quiver plot
|
||||||
# im = plt.imshow(np.reshape(R, (n,n)))
|
# im = plt.imshow(np.reshape(R, (n,n)))
|
||||||
@@ -113,104 +114,160 @@ def plot_distortions(xe, ye, xp, yp, lims=False, add_detectors=True,
|
|||||||
plt.close()
|
plt.close()
|
||||||
|
|
||||||
# Initiate the figure
|
# Initiate the figure
|
||||||
# fig = plt.figure(figsize=(9.6,4.8))
|
fig = plt.figure(figsize=(12,4.8))
|
||||||
# ax = fig.add_subplot(121, aspect='equal')
|
gs = GridSpec(ncols=3, nrows=2, width_ratios=[2,1,1], height_ratios=[1,1])#left=0.05, right=0.48, wspace=0.05)
|
||||||
# ax2 = fig.add_subplot(122, aspect='equal')
|
ax = fig.add_subplot(gs[:, :1])
|
||||||
fig, axes = plt.subplots(ncols=2,
|
ax2 = fig.add_subplot(gs[0, 1])
|
||||||
nrows=1,
|
ax3 = fig.add_subplot(gs[0, 2])
|
||||||
gridspec_kw={'width_ratios': [1,1]},
|
ax4 = fig.add_subplot(gs[1, 1])
|
||||||
figsize=(9.6,4.8))
|
ax5 = fig.add_subplot(gs[1, 2])
|
||||||
ax, ax2 = axes
|
|
||||||
ax.set_aspect('equal')
|
axilist = [ax, ax2, ax3, ax4, ax5]
|
||||||
ax2.set_aspect('equal')
|
for axi in axilist:
|
||||||
|
axi.set_aspect('equal')
|
||||||
|
|
||||||
# Add the detector layout if so desired.
|
# Add the detector layout if so desired.
|
||||||
if add_detectors:
|
if add_detectors:
|
||||||
add_detector_layout((fig,ax), lw=.8, alpha=1, show_label=False)
|
add_detector_layout((fig,ax), lw=1, alpha=1, show_label=False)
|
||||||
|
|
||||||
# Plot the vector plot
|
# Plot the vector plot
|
||||||
xe = np.asarray(xe[:121]).reshape((11,11))
|
xe = np.asarray(xe[:121]).reshape((11,11))
|
||||||
ye = np.asarray(ye[:121]).reshape((11,11))
|
ye = np.asarray(ye[:121]).reshape((11,11))
|
||||||
# for i in range(len(xe)):
|
|
||||||
# ax.plot(xe[:,i], ye[:,i], 'k-', alpha=0.2, linewidth=.5)
|
|
||||||
# ax.plot(xe[i,:], ye[i,:], 'k-', alpha=0.2, linewidth=.5)
|
|
||||||
# ax.quiver(X,Y,dx,dy,R, alpha=1, units='dots', zorder=300)
|
|
||||||
|
|
||||||
for k in range(4):
|
# Now we iterate over the different iterations of the GD simulations
|
||||||
print()
|
print('Total number of grids: {}'.format(no_of_grids))
|
||||||
|
for k in range(no_of_grids):
|
||||||
|
|
||||||
|
# Selecting the different iterations (11x11 grid, but flattened)
|
||||||
ind_end = (k+1) * 121
|
ind_end = (k+1) * 121
|
||||||
ind_start = k * 121
|
ind_start = k * 121
|
||||||
dpix = np.diff(Y)[ind_start:ind_end][1]
|
dpix = np.diff(Y)[ind_start:ind_end][1]
|
||||||
print(k, ind_start, ind_end, dpix)
|
|
||||||
|
|
||||||
|
# Coordinates of the grid in this iteration
|
||||||
xplot = np.asarray(X[ind_start:ind_end]).reshape((11,11))
|
xplot = np.asarray(X[ind_start:ind_end]).reshape((11,11))
|
||||||
yplot = np.asarray(Y[ind_start:ind_end]).reshape((11,11))
|
yplot = np.asarray(Y[ind_start:ind_end]).reshape((11,11))
|
||||||
yplot, xplot = np.mgrid[yplot.min()+dpix/2:yplot.max()-dpix/2:12j,
|
yplot, xplot = np.mgrid[yplot.min()+dpix/2:yplot.max()-dpix/2:12j,
|
||||||
xplot.min()+dpix/2:xplot.max()-dpix/2:12j]
|
xplot.min()+dpix/2:xplot.max()-dpix/2:12j]
|
||||||
|
|
||||||
|
# Magnitude of the distortion at coordinates xplot, yplot
|
||||||
|
# Used to color the background
|
||||||
Rtemp = np.asarray(R[ind_start:ind_end]).reshape((11,11))
|
Rtemp = np.asarray(R[ind_start:ind_end]).reshape((11,11))
|
||||||
ax.pcolor(-1*yplot.T, -1*xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
shiftx = X[ind_start:ind_end][61]
|
||||||
# ax2.pcolor(-1*xplot.T, -1*yplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=1, vmax=100))
|
|
||||||
shiftx = X[ind_start:ind_end][61]#np.abs(dpix)/2
|
|
||||||
shifty = Y[ind_start:ind_end][60]
|
shifty = Y[ind_start:ind_end][60]
|
||||||
print(Y[ind_start:ind_end])
|
|
||||||
print('shiftx:', shiftx)
|
|
||||||
print('shifty:', shifty)
|
|
||||||
|
|
||||||
# ax2.pcolor(k*shifty-1*yplot.T, k*shiftx-1*xplot.T, Rtemp.T*10, cmap=cmap, norm=LogNorm(vmin=1, vmax=100))
|
|
||||||
if k == 1: ax2.pcolor(shifty-1*yplot.T, shiftx-1*xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
if k in [0,1,2,3,7]: # Plot the center part pcolor
|
||||||
elif k == 2: ax2.pcolor(2*shifty-1*yplot.T, 2*shiftx-1*xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
ax.pcolor(1*shifty-1*yplot.T, 1*shiftx-1*xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
||||||
elif k == 3: ax2.pcolor(2*shifty-1*yplot.T, 2*shiftx-1*xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
# if k > 3: # Plot the zoom and megazoom
|
||||||
|
ax2.pcolor(2*shifty-1*yplot.T, 2*shiftx-1*xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
||||||
|
ax3.pcolor(2*shifty-1*yplot.T, 2*shiftx-1*xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
||||||
|
if k in [0,4,5,6,8]: # Plot the left bottom part pcolor
|
||||||
|
if k!=0:
|
||||||
|
ax.pcolor(yplot.T, xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
||||||
|
ax4.pcolor(2*shifty-1*yplot.T, 2*shiftx-1*xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
||||||
|
ax5.pcolor(2*shifty-1*yplot.T, 2*shiftx-1*xplot.T, Rtemp.T, cmap=cmap, norm=LogNorm(vmin=vmin, vmax=vmax))
|
||||||
|
|
||||||
|
# Quiver plots
|
||||||
|
# Full field plot
|
||||||
if k == 0:
|
if k == 0:
|
||||||
ax.quiver(X[ind_start:ind_end],Y[ind_start:ind_end],
|
ax.quiver(X[ind_start:ind_end],Y[ind_start:ind_end],
|
||||||
dx[ind_start:ind_end],dy[ind_start:ind_end],
|
dx[ind_start:ind_end],dy[ind_start:ind_end],
|
||||||
angles='xy', edgecolor='k', facecolor='k',
|
angles='xy', edgecolor='k', facecolor='k',
|
||||||
linewidth=.8, zorder=300, alpha=1, scale=1.4e-5,
|
linewidth=.8, zorder=300, alpha=1, scale=1.2e-5,
|
||||||
units='dots')
|
units='dots')
|
||||||
elif k in [2,3]:
|
# Center plot zoom
|
||||||
|
if k in [0,1,2]:
|
||||||
ax2.quiver(X[ind_start:ind_end],Y[ind_start:ind_end],
|
ax2.quiver(X[ind_start:ind_end],Y[ind_start:ind_end],
|
||||||
dx[ind_start:ind_end],dy[ind_start:ind_end],
|
dx[ind_start:ind_end],dy[ind_start:ind_end],
|
||||||
angles='xy', edgecolor='k', facecolor='k',
|
angles='xy', edgecolor='k', facecolor='k',
|
||||||
linewidth=.8, zorder=300, alpha=1, scale=0.2e-5,
|
linewidth=.8, zorder=300, alpha=1, scale=7e-7,
|
||||||
units='dots')
|
units='dots')
|
||||||
# ax.pcolor(xplot * (1 - dpix/105), yplot * (1 - dpix/105), Rtemp, cmap='jet', norm=LogNorm(vmin=1, vmax=100))
|
|
||||||
|
|
||||||
ax.set_xlabel('x (mm)', fontsize=16)
|
# Center plot megazoom
|
||||||
ax.set_ylabel('y (mm)', fontsize=16)
|
elif k in [2,3,7]:
|
||||||
ax.tick_params(axis='both', direction='in', labelsize=14, zorder=-1,
|
ax3.quiver(X[ind_start:ind_end],Y[ind_start:ind_end],
|
||||||
top=True, right=True)
|
dx[ind_start:ind_end],dy[ind_start:ind_end],
|
||||||
ax2.set_xlabel('x (mm)', fontsize=16)
|
angles='xy', edgecolor='k', facecolor='k',
|
||||||
ax2.set_ylabel('y (mm)', fontsize=16)
|
linewidth=.8, zorder=300, alpha=1, scale=1e-6,
|
||||||
ax2.tick_params(axis='both', direction='in', labelsize=14, zorder=-1,
|
units='dots')
|
||||||
|
|
||||||
|
# Left bottom zoom
|
||||||
|
if k in [4,5]:
|
||||||
|
ax4.quiver(X[ind_start:ind_end],Y[ind_start:ind_end],
|
||||||
|
dx[ind_start:ind_end],dy[ind_start:ind_end],
|
||||||
|
angles='xy', edgecolor='k', facecolor='k',
|
||||||
|
linewidth=.8, zorder=300, alpha=1, scale=1.2e-5,
|
||||||
|
units='dots')
|
||||||
|
|
||||||
|
if k in [5,6,8]:
|
||||||
|
ax5.quiver(X[ind_start:ind_end],Y[ind_start:ind_end],
|
||||||
|
dx[ind_start:ind_end],dy[ind_start:ind_end],
|
||||||
|
angles='xy', edgecolor='k', facecolor='k',
|
||||||
|
linewidth=.8, zorder=300, alpha=1, scale=7e-6,
|
||||||
|
units='dots')
|
||||||
|
|
||||||
|
# Adjusting how the axes look in all subfigures
|
||||||
|
for axi in [ax, ax2, ax4]:
|
||||||
|
axi.set_ylabel('y (mm)', fontsize=16)
|
||||||
|
for axi in [ax, ax4, ax5]:
|
||||||
|
axi.set_xlabel('x (mm)', fontsize=16)
|
||||||
|
for axi in axilist:
|
||||||
|
axi.tick_params(axis='both', direction='in', labelsize=14, zorder=-1,
|
||||||
top=True, right=True)
|
top=True, right=True)
|
||||||
|
|
||||||
|
# Setting some limits to the subplots
|
||||||
cb = fig.colorbar(im, ax=axes, fraction=0.025, pad=0.04)
|
|
||||||
cb.set_label(label='PSF centroid shift (μas)', size=14)
|
|
||||||
cb.ax.tick_params(labelsize=14)
|
|
||||||
|
|
||||||
lbls = 10**np.asarray(cb.ax.get_yticks())
|
|
||||||
print(lbls)
|
|
||||||
newlbls = ['{:.0f}'.format(x) for x in 10**np.asarray(cb.ax.get_yticks())]
|
|
||||||
newlbls[1] = '{:.1f}'.format(lbls[1])
|
|
||||||
newlbls[0] = '{:.1f}'.format(lbls[0])
|
|
||||||
cb.ax.set_yticklabels(newlbls)
|
|
||||||
print(cb.ax.get_yticks())
|
|
||||||
if not lims:
|
if not lims:
|
||||||
ax.set_xlim([-125, 115])
|
ax.set_xlim([-125, 115])
|
||||||
ax.set_ylim([-115, 115])
|
ax.set_ylim([-115, 115])
|
||||||
elif lims:
|
elif lims:
|
||||||
ax.set_xlim(lims[0])
|
ax.set_xlim(lims[0])
|
||||||
ax.set_ylim(lims[1])
|
ax.set_ylim(lims[1])
|
||||||
ax2.set_xlim([-2.01,2.75])
|
ax2.set_xlim([-1+0.3513,1+0.3513])
|
||||||
ax2.set_ylim([-2.01,2.75])
|
ax2.set_ylim([-1+0.3513,1+0.3513])
|
||||||
ax.indicate_inset_zoom(ax2, edgecolor="black")
|
ax3.set_xlim([-0.01+0.3513, 0.01+0.3513])
|
||||||
|
ax3.set_ylim([-0.01+0.3513, 0.01+0.3513])
|
||||||
|
# ax4.set_xlim([-2.01-84,2.75-84])
|
||||||
|
# ax4.set_ylim([-2.01-84,2.75-84])
|
||||||
|
ax4.set_xlim([-83.6-1,-83.6+1])
|
||||||
|
ax4.set_ylim([-83.6-1,-83.6+1])
|
||||||
|
ax5.set_xlim([-0.01-83.6070, 0.01-83.6070])
|
||||||
|
ax5.set_ylim([-0.01-83.6070, 0.01-83.6070])
|
||||||
|
|
||||||
|
# For the center inset
|
||||||
|
ax.indicate_inset_zoom(ax2, edgecolor='black')
|
||||||
|
ax2.indicate_inset_zoom(ax3, edgecolor='black')
|
||||||
|
|
||||||
|
# For the off-center inset
|
||||||
|
ax.indicate_inset_zoom(ax4, edgecolor='black')
|
||||||
|
ax4.indicate_inset_zoom(ax5, edgecolor='black')
|
||||||
|
|
||||||
|
# after plotting the data, format the labels
|
||||||
|
ax5.set_xticklabels(['{:.2f}'.format(x) for x in ax5.get_xticks()])
|
||||||
|
ax5.set_yticklabels(['{:.2f}'.format(x) for x in ax5.get_yticks()])
|
||||||
|
|
||||||
fig.subplots_adjust(top=1.0,
|
fig.subplots_adjust(top=1.0,
|
||||||
bottom=0.0,
|
bottom=0.08,
|
||||||
left=0.1,
|
left=0.075,
|
||||||
right=0.8,
|
right=0.88,
|
||||||
hspace=0.135,
|
hspace=0.145,
|
||||||
wspace=0.3)
|
wspace=0.45)
|
||||||
|
|
||||||
|
# Setting and modifying the colorbar
|
||||||
|
fig.subplots_adjust(right=0.88)
|
||||||
|
cbar_ax = fig.add_axes([0.9, 0.12, 0.02, 0.85])
|
||||||
|
cb = fig.colorbar(im, cax=cbar_ax)
|
||||||
|
cb.set_label(label='PSF centroid shift (μas)', size=14)
|
||||||
|
cb.ax.tick_params(labelsize=14)
|
||||||
|
|
||||||
|
lbls = 10**np.asarray(cb.ax.get_yticks())
|
||||||
|
|
||||||
|
newlbls = ['{:.0f}'.format(x) for x in 10**np.asarray(cb.ax.get_yticks())]
|
||||||
|
newlbls[3] = '{:.1f}'.format(lbls[3])
|
||||||
|
newlbls[2] = '{:.1f}'.format(lbls[2])
|
||||||
|
newlbls[1] = '{:.2f}'.format(lbls[1])
|
||||||
|
newlbls[0] = '{:.2f}'.format(lbls[0])
|
||||||
|
cb.ax.set_yticklabels(newlbls)
|
||||||
|
|
||||||
# plt.tight_layout()
|
# plt.tight_layout()
|
||||||
if save:
|
if save:
|
||||||
plt.savefig('{}.pdf'.format(figtitle),
|
plt.savefig('{}.pdf'.format(figtitle),
|
||||||
@@ -228,51 +285,127 @@ def plot_distortions(xe, ye, xp, yp, lims=False, add_detectors=True,
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
ps = ParaxialMICADO(n=3001, m=3001, dpix=50, l=1.49e-3).platescale
|
ps = ParaxialMICADO(n=3001, m=3001, dpix=50, l=1.49e-3).platescale
|
||||||
print(ps)
|
|
||||||
|
|
||||||
plt.rc('font', family='serif')
|
plt.rc('font', family='serif')
|
||||||
plt.rc('axes', labelsize='large')
|
plt.rc('axes', labelsize='large')
|
||||||
|
|
||||||
# convert_detector_size()
|
# convert_detector_size()
|
||||||
# Plotting the original distortions
|
# Plotting the original distortions, -1/11 :1/11
|
||||||
data_dir = '../data/GD Focal Plane WFEs/'
|
data_dir = '../data/GD Focal Plane WFEs/'
|
||||||
xe_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
xe_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
ye_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
ye_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
xp_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
xp_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
yp_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
yp_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
# Zoom 1:
|
# # Zoom 1: -1/11 :1/11
|
||||||
xe_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
# xe_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
ye_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
# ye_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
xp_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
# xp_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
yp_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
# yp_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
# Zoom 2
|
# # Zoom 2: -.5/11:.5/11
|
||||||
xe_og2 = load_variable(data_dir + 'GD_IFP_zoom2_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
# xe_og2 = load_variable(data_dir + 'GD_IFP_zoom2_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
ye_og2 = load_variable(data_dir + 'GD_IFP_zoom2_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
# ye_og2 = load_variable(data_dir + 'GD_IFP_zoom2_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
xp_og2 = load_variable(data_dir + 'GD_IFP_zoom2_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
# xp_og2 = load_variable(data_dir + 'GD_IFP_zoom2_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
yp_og2 = load_variable(data_dir + 'GD_IFP_zoom2_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
# yp_og2 = load_variable(data_dir + 'GD_IFP_zoom2_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
# Zoom 3
|
# # Zoom 3: -.1/11:.1/11
|
||||||
xe_og3 = load_variable(data_dir + 'GD_IFP_zoom3_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
# xe_og3 = load_variable(data_dir + 'GD_IFP_zoom3_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
ye_og3 = load_variable(data_dir + 'GD_IFP_zoom3_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
# ye_og3 = load_variable(data_dir + 'GD_IFP_zoom3_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
xp_og3 = load_variable(data_dir + 'GD_IFP_zoom3_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
# xp_og3 = load_variable(data_dir + 'GD_IFP_zoom3_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
yp_og3 = load_variable(data_dir + 'GD_IFP_zoom3_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
# yp_og3 = load_variable(data_dir + 'GD_IFP_zoom3_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
xe = np.append(xe_og, [xe_og1, xe_og2, xe_og3])
|
# Zoom 97: -1/11: 1/11
|
||||||
ye = np.append(ye_og, [ye_og1, ye_og2, ye_og3])
|
xe_og1 = load_variable(data_dir + 'GD_IFP_zoom97_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
xp = np.append(xp_og, [xp_og1, xp_og2, xp_og3])
|
ye_og1 = load_variable(data_dir + 'GD_IFP_zoom97_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
yp = np.append(yp_og, [yp_og1, yp_og2, yp_og3])
|
xp_og1 = load_variable(data_dir + 'GD_IFP_zoom97_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og1 = load_variable(data_dir + 'GD_IFP_zoom97_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
# xe = np.append(xe_og2, xe_og3)
|
# Zoom 98: -1/121 : 1/121
|
||||||
# ye = np.append(ye_og2, ye_og3)
|
xe_og2 = load_variable(data_dir + 'GD_IFP_zoom98_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
# xp = np.append(xp_og2, xp_og3)
|
ye_og2 = load_variable(data_dir + 'GD_IFP_zoom98_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
# yp = np.append(yp_og2, yp_og3)
|
xp_og2 = load_variable(data_dir + 'GD_IFP_zoom98_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og2 = load_variable(data_dir + 'GD_IFP_zoom98_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
# Zoom 99: -1/11**3 : -1/11**3
|
||||||
|
xe_og3 = load_variable(data_dir + 'GD_IFP_zoom99_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
|
ye_og3 = load_variable(data_dir + 'GD_IFP_zoom99_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
xp_og3 = load_variable(data_dir + 'GD_IFP_zoom99_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og3 = load_variable(data_dir + 'GD_IFP_zoom99_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
|
||||||
figtitle = '../figures adapted for thesis/Focal Plane/GD_IFP_zern'
|
# Zoom7: -.01/11:.01/11
|
||||||
plot_distortions(xe, ye, xp, yp, show=True, save=True, figtitle=figtitle,
|
xe_og4 = load_variable(data_dir + 'GD_IFP_zoom92_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
|
ye_og4 = load_variable(data_dir + 'GD_IFP_zoom92_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
xp_og4 = load_variable(data_dir + 'GD_IFP_zoom92_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og4 = load_variable(data_dir + 'GD_IFP_zoom92_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
# Zoom8: -.05/11:.05/11 - not plotted
|
||||||
|
# Zoom93: -.004/11:.004/11
|
||||||
|
xe_og5 = load_variable(data_dir + 'GD_IFP_zoom93_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
|
ye_og5 = load_variable(data_dir + 'GD_IFP_zoom93_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
xp_og5 = load_variable(data_dir + 'GD_IFP_zoom93_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og5 = load_variable(data_dir + 'GD_IFP_zoom93_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
# # Zoom91: -.01/11:.01/11 but hx and hy shifted to an area near the corner of the image,
|
||||||
|
# # where distortion is supposed to be large
|
||||||
|
# xe_og6 = load_variable(data_dir + 'GD_IFP_zoom91_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
|
# ye_og6 = load_variable(data_dir + 'GD_IFP_zoom91_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
# xp_og6 = load_variable(data_dir + 'GD_IFP_zoom91_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
# yp_og6 = load_variable(data_dir + 'GD_IFP_zoom91_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
# Zoom94: -1/11:1/11 but hx and hy shifted to an area near the corner of the image,
|
||||||
|
# where distortion is supposed to be large
|
||||||
|
xe_og6 = load_variable(data_dir + 'GD_IFP_zoom94_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
|
ye_og6 = load_variable(data_dir + 'GD_IFP_zoom94_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
xp_og6 = load_variable(data_dir + 'GD_IFP_zoom94_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og6 = load_variable(data_dir + 'GD_IFP_zoom94_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
# Zoom95: -1/121:1/121 but hx and hy shifted to an area near the corner of the image,
|
||||||
|
# where distortion is supposed to be large
|
||||||
|
xe_og7 = load_variable(data_dir + 'GD_IFP_zoom95_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
|
ye_og7 = load_variable(data_dir + 'GD_IFP_zoom95_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
xp_og7 = load_variable(data_dir + 'GD_IFP_zoom95_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og7 = load_variable(data_dir + 'GD_IFP_zoom95_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
# Zoom96: -1/11**3:1/11**3 but hx and hy shifted to an area near the corner of the image,
|
||||||
|
# where distortion is supposed to be large
|
||||||
|
xe_og8 = load_variable(data_dir + 'GD_IFP_zoom96_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
|
ye_og8 = load_variable(data_dir + 'GD_IFP_zoom96_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
xp_og8 = load_variable(data_dir + 'GD_IFP_zoom96_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og8 = load_variable(data_dir + 'GD_IFP_zoom96_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
# Zoom 100: - 1/11**4:1/11**4, phase interpolation, center of the field
|
||||||
|
xe_og9 = load_variable(data_dir + 'GD_IFP_zoom100_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
|
ye_og9 = load_variable(data_dir + 'GD_IFP_zoom100_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
xp_og9 = load_variable(data_dir + 'GD_IFP_zoom100_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og9 = load_variable(data_dir + 'GD_IFP_zoom100_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
# Zoom 101: - 1/11**4:1/11**4, phase interpolation, center of the field, with shift to left bottom corner
|
||||||
|
xe_og10 = load_variable(data_dir + 'GD_IFP_zoom101_obscured_PSF_xcentroid_expected_zern_psd.pkl')
|
||||||
|
ye_og10 = load_variable(data_dir + 'GD_IFP_zoom101_obscured_PSF_ycentroid_expected_zern_psd.pkl')
|
||||||
|
xp_og10 = load_variable(data_dir + 'GD_IFP_zoom101_obscured_PSF_xcentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
yp_og10 = load_variable(data_dir + 'GD_IFP_zoom101_obscured_PSF_ycentroid_found_with_wfe_airy_zern_psd.pkl')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Combining the data points
|
||||||
|
# xe = np.append(xe_og, [xe_og1, xe_og2, xe_og3, xe_og4, xe_og5, xe_og6, xe_og7, xe_og8])
|
||||||
|
# ye = np.append(ye_og, [ye_og1, ye_og2, ye_og3, ye_og4, ye_og5, ye_og6, ye_og7, ye_og8])
|
||||||
|
# xp = np.append(xp_og, [xp_og1, xp_og2, xp_og3, xp_og4, xp_og5, xp_og6, xp_og7, xp_og8])
|
||||||
|
# yp = np.append(yp_og, [yp_og1, yp_og2, yp_og3, yp_og4, yp_og5, yp_og6, yp_og7, yp_og8])
|
||||||
|
xe = np.append(xe_og, [xe_og1, xe_og2, xe_og3, xe_og6, xe_og7, xe_og8, xe_og9, xe_og10])
|
||||||
|
ye = np.append(ye_og, [ye_og1, ye_og2, ye_og3, ye_og6, ye_og7, ye_og8, ye_og9, ye_og10])
|
||||||
|
xp = np.append(xp_og, [xp_og1, xp_og2, xp_og3, xp_og6, xp_og7, xp_og8, xp_og9, xp_og10])
|
||||||
|
yp = np.append(yp_og, [yp_og1, yp_og2, yp_og3, yp_og6, yp_og7, yp_og8, yp_og9, yp_og10])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
figtitle = '../figures adapted for thesis/Focal Plane/GD_IFP_psd'
|
||||||
|
plot_distortions(xe, ye, xp, yp, show=False, save=True, figtitle=figtitle,
|
||||||
lims=[[-120,120],[-120,120]])
|
lims=[[-120,120],[-120,120]])
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ def plot_distortions2(xe, ye, xp, yp, lims=False, add_detectors=True,
|
|||||||
# ax.plot(xe[i,:], ye[i,:], 'k-', alpha=0.2, linewidth=.5)
|
# ax.plot(xe[i,:], ye[i,:], 'k-', alpha=0.2, linewidth=.5)
|
||||||
# ax.quiver(X,Y,dx,dy,R, alpha=1, units='dots', zorder=300)
|
# ax.quiver(X,Y,dx,dy,R, alpha=1, units='dots', zorder=300)
|
||||||
|
|
||||||
for k in range(1):
|
for k in range(3):
|
||||||
print()
|
print()
|
||||||
ind_end = (k+1) * 121
|
ind_end = (k+1) * 121
|
||||||
ind_start = k * 121
|
ind_start = k * 121
|
||||||
@@ -300,30 +300,30 @@ if __name__ == '__main__':
|
|||||||
# convert_detector_size()
|
# convert_detector_size()
|
||||||
# Plotting the original distortions
|
# Plotting the original distortions
|
||||||
data_dir = '../data/GD Focal Plane WFEs/'
|
data_dir = '../data/GD Focal Plane WFEs/'
|
||||||
xe_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_xcentroid_expected_zern.pkl')
|
xe_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_xcentroid_expected_psd.pkl')
|
||||||
ye_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_ycentroid_expected_zern.pkl')
|
ye_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_ycentroid_expected_psd.pkl')
|
||||||
xp_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_xcentroid_found_with_wfe_airy_zern.pkl')
|
xp_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_xcentroid_found_with_wfe_airy_psd.pkl')
|
||||||
yp_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_ycentroid_found_with_wfe_airy_zern.pkl')
|
yp_og = load_variable(data_dir + 'GD_IFP_obscured_PSF_ycentroid_found_with_wfe_airy_psd.pkl')
|
||||||
|
|
||||||
# # Zoom 1:
|
# # Zoom 1:
|
||||||
# xe_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_xcentroid_expected_zern.pkl')
|
xe_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_xcentroid_expected_psd.pkl')
|
||||||
# ye_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_ycentroid_expected_zern.pkl')
|
ye_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_ycentroid_expected_psd.pkl')
|
||||||
# xp_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_xcentroid_found_with_wfe_airy_zern.pkl')
|
xp_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_xcentroid_found_with_wfe_airy_psd.pkl')
|
||||||
# yp_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_ycentroid_found_with_wfe_airy_zern.pkl')
|
yp_og1 = load_variable(data_dir + 'GD_IFP_zoom_obscured_PSF_ycentroid_found_with_wfe_airy_psd.pkl')
|
||||||
|
|
||||||
xe = xe_og#np.append(xe_og, xe_og1)
|
xe = np.append(xe_og, xe_og1)
|
||||||
ye = ye_og#np.append(ye_og, ye_og1)
|
ye = np.append(ye_og, ye_og1)
|
||||||
xp = xp_og#np.append(xp_og, xp_og1)
|
xp = np.append(xp_og, xp_og1)
|
||||||
yp = yp_og#np.append(yp_og, yp_og1)
|
yp = np.append(yp_og, yp_og1)
|
||||||
|
|
||||||
# xe = np.append(xe_og2, xe_og3)
|
xe = np.append(xe_og2, xe_og3)
|
||||||
# ye = np.append(ye_og2, ye_og3)
|
ye = np.append(ye_og2, ye_og3)
|
||||||
# xp = np.append(xp_og2, xp_og3)
|
xp = np.append(xp_og2, xp_og3)
|
||||||
# yp = np.append(yp_og2, yp_og3)
|
yp = np.append(yp_og2, yp_og3)
|
||||||
|
|
||||||
|
|
||||||
figtitle = '../figures adapted for thesis/Focal Plane/GD_IFP_zern'
|
figtitle = '../figures adapted for thesis/Focal Plane/GD_IFP_zern2'
|
||||||
plot_distortions(xe, ye, xp, yp, show=True, save=False, figtitle=figtitle,
|
plot_distortions2(xe, ye, xp, yp, show=True, save=False, figtitle=figtitle,
|
||||||
lims=[[-120,120],[-120,120]])
|
lims=[[-120,120],[-120,120]])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from numpy.polynomial import polynomial
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, '/Users/joost/Dropbox/Werk/PhD/Documents/Published/FourierOptics GitHub release/')
|
||||||
|
from fourierOptics import *
|
||||||
|
from pdb import set_trace
|
||||||
|
|
||||||
|
def polyfit2d(x, y, z, deg):
|
||||||
|
x = np.asarray(x)
|
||||||
|
y = np.asarray(y)
|
||||||
|
z = np.asarray(z)
|
||||||
|
deg = np.asarray(deg)
|
||||||
|
vander = polynomial.polyvander2d(x, y, deg)
|
||||||
|
vander = vander.reshape((-1,vander.shape[-1])) # Wat gebeurt hier? reshape(-1) lijkt niets te doen?
|
||||||
|
z = z.reshape((vander.shape[0],))
|
||||||
|
c = np.linalg.lstsq(vander, z, rcond=None)[0]
|
||||||
|
return c.reshape(deg+1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
plt.rc('text', usetex=True)
|
||||||
|
plt.rc('font', family='serif')
|
||||||
|
|
||||||
|
# Initializing MICADO paraxial model
|
||||||
|
mcd = ParaxialMICADO(n=3001, m=3001, dpix=50)
|
||||||
|
wfe = WavefrontError(mcd.n, mcd.m)
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
l = 1.49e-3
|
||||||
|
|
||||||
|
# Set field points
|
||||||
|
hxList = [0]
|
||||||
|
hyList = [0]
|
||||||
|
|
||||||
|
wfe_p1 = load_variable('../data/compressed items/ADC_tWFE_p1_zern_20nm_psd_15nm.pkl')
|
||||||
|
wfe_p2 = load_variable('../data/compressed items/ADC_tWFE_p2_zern_20nm_psd_15nm.pkl')
|
||||||
|
wfe_p3 = load_variable('../data/compressed items/ADC_tWFE_p3_zern_20nm_psd_15nm.pkl')
|
||||||
|
wfe_p4 = load_variable('../data/compressed items/ADC_tWFE_p4_zern_20nm_psd_15nm.pkl')
|
||||||
|
|
||||||
|
# wfe_p1 = load_variable('../data/compressed items/ADC_tWFE_p1_psd_25nm.pkl')
|
||||||
|
# wfe_p2 = load_variable('../data/compressed items/ADC_tWFE_p2_psd_25nm.pkl')
|
||||||
|
# wfe_p3 = load_variable('../data/compressed items/ADC_tWFE_p3_psd_25nm.pkl')
|
||||||
|
# wfe_p4 = load_variable('../data/compressed items/ADC_tWFE_p4_psd_25nm.pkl')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
prop_surf = 4
|
||||||
|
E, x, y = mcd.propagate(l=l,surface=prop_surf, zoom=False, show=False,
|
||||||
|
print_progress=True, hx=0, hy=0)
|
||||||
|
# Save the resulting 'perfect' PSF for later
|
||||||
|
tx_combined = 0
|
||||||
|
ty_combined = 0
|
||||||
|
|
||||||
|
print(mcd.ELT_ADC.p1.CA)
|
||||||
|
|
||||||
|
for wfe_surf in [wfe_p1, wfe_p2, wfe_p3, wfe_p4]:
|
||||||
|
|
||||||
|
# Don't show anything outside the clear aperture.
|
||||||
|
mask = np.sqrt(x**2 + y**2) > 40#mcd.ELT_ADC.p1.CA/2
|
||||||
|
# Plot P1
|
||||||
|
phasescreenMasked = wfe_surf.copy()
|
||||||
|
wfe_p1[mask] = np.nan
|
||||||
|
phasescreenMasked[mask] = 0
|
||||||
|
|
||||||
|
# Bepaling van de gemiddelde tilt voor deze coordinaten, i.e. een lineaire fit.
|
||||||
|
pf1 = polyfit2d(x.real[~mask], y.real[~mask], phasescreenMasked[~mask], [1,1])
|
||||||
|
|
||||||
|
# Coefficienten van de fit vertaalt naar graden tilt
|
||||||
|
o1x = np.arctan(pf1[1,0])
|
||||||
|
o1y = np.arctan(pf1[0,1])
|
||||||
|
print(o1x, o1y)
|
||||||
|
o1x_deg = np.degrees(o1x)
|
||||||
|
|
||||||
|
o1y_deg = np.degrees(o1y)
|
||||||
|
tx_combined += o1x
|
||||||
|
ty_combined += o1y
|
||||||
|
print('tx: {} rad ({} deg = {:.2f} arcsec)'.format(o1x, o1x_deg, o1x_deg*3600))
|
||||||
|
print('ty: {} rad ({} deg = {:.2f} arcsec)'.format(o1y, o1y_deg, o1y_deg*3600))
|
||||||
|
|
||||||
|
print('Combined results:\n-----------------')
|
||||||
|
print('tx: {} rad --> distortion of {} μas'.format(tx_combined, 1601.688*tx_combined*0.267*1e6))
|
||||||
|
print('ty: {} rad --> distortion of {} μas'.format(ty_combined, 1601.688*ty_combined*0.267*1e6))
|
||||||
|
tr_combined = np.sqrt(tx_combined**2 + ty_combined**2)
|
||||||
|
print('tr: {} rad --> distortion of {} μas'.format(tr_combined, 1601.688*tr_combined*0.267*1e6))
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 145 KiB |
Reference in new issue
Block a user