Files
fourierOptics/scripts/MICADO_paraxial_system_dispersion.py

260 lines
8.9 KiB
Python

#!/usr/bin/env Python3
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FormatStrFormatter
from matplotlib.colors import LogNorm
import time
from scipy import interpolate
import sys
sys.path.insert(0, '/Users/joost/Dropbox/Werk/PhD/Documents/Published/FourierOptics GitHub release/')
from fourierOptics import *
'''
Description:
This early script simulates a dispersed PSF. By rotating the
ADC prisms we can inspect the change in the dispersion.
The theoretical best position of the ADC did not result in
an undispersed PSF, for some reason.
'''
def perform_padding(A, xs, ys):
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)
y_margin = int((ys - A.shape[1])/2)
return np.pad(A, (x_margin, y_margin))
def find_nearest(array, value):
array = np.asarray(array)
diff = (np.abs(array - value)).argmin()
idx = np.unravel_index(diff, array.shape)
return idx
def find_maximum(array):
idx = np.unravel_index(array.argmax(), array.shape)
return idx
def select_subsection(x, y , outputCoordinates):
select_1 = find_nearest(x, outputCoordinates[0])[1]
select_2 = find_nearest(x, outputCoordinates[1])[1]
select_3 = find_nearest(y, outputCoordinates[2])[0]
select_4 = find_nearest(y, outputCoordinates[3])[0]
return [select_1, select_2, select_3, select_4]
def perform_extrapolation(x, y, n, m):
# Determine properties of x,y meshgrid
xshape = x.shape[0]
yshape = y.shape[0]
dpix = (np.abs(np.min(x)) + np.abs(np.max(x))) / (xshape-1)
# Extrapolate from, and include, the old x,y meshgrid
xnew = np.linspace(-(n-1)/2*dpix, (n-1)/2*dpix, n)
ynew = np.linspace(-(m-1)/2*dpix, (m-1)/2*dpix, m)
xnew, ynew = np.meshgrid(xnew, ynew)
return xnew, ynew
if __name__ == '__main__':
plt.rc('font', family='serif')
plt.rc('axes', labelsize='large')
# Dispersion levels:
lList = np.linspace(1.49e-3, 1.78e-3, 2).tolist()
dispMax = 17.9e-3 / 3600 # dispersion in degrees
dispersion = np.linspace(0, dispMax, len(lList)).tolist()
Exyz_list = []
# Input parameters:
dpix = 50
n, m = 3001, 3001
x, y = np.meshgrid(np.linspace(-n/2*dpix, n/2*dpix, n), np.linspace(-m/2*dpix, m/2*dpix, m))
print ('Your resolution is {}x{} with a pixel size of {}'.format(n,m,dpix))
print('This means your grid is {} mm by {} mm, with each pixel {} mm.'.format(x.max()-x.min(), y.max()-y.min(), dpix))
###########################################################
#################### SETTING UP MICADO ####################
###########################################################
# Define the ELT mask (the spiders and central obscuration)
prof = Profiles()
# ELT_MASK = prof.top_hat(19427, n,m,dpix)#.astype('float64')
# ELT_MASK = prof.obscured_top_hat(4000, 500, n, m, dpix)
ELT_MASK = prof.ELT_pupil(n,m,dpix)
# plt.imshow(ELT_MASK);plt.colorbar();plt.show()
###########################################################
for l in lList:
i = lList.index(l)
print('Wavelength is {:.6f} mm. ({:02d}/{}).'.format(l,lList.index(l)+1, len(lList)))
x, y = np.meshgrid(np.linspace(-n/2*dpix, n/2*dpix, n), np.linspace(-m/2*dpix, m/2*dpix, m))
fou = FourierOptics(l=l)
wfe = WavefrontError(n,m)
dispersion_tilt = wfe.generate_tilt(x, y, tx=0, ty=dispersion[i])
# ELT Mirror system combined into a single lens
ELT_MIRROR = ParabolicMirror(dx=0, dy=0, name='ELT-paraxial', CA=38542, f=6.84022e5)
ELT_FP = OpticalSurface(name='MCD-IFP')
ELT_COL = ParaxialLens(CA=154.54, f=1418.94, name='MCD-COL')
ELT_ADC = ADCObject()
optAngle = ELT_ADC.find_optimum_angle(17.9, lList[0], lList[-1])
print(optAngle)
print('ADC angle now set to {:.4f}'.format(ELT_ADC.theta))
# ELT_ADC.set_orientation(180)
ELT_ADC.set_orientation(-optAngle+90)
ELT_CAM = ParaxialLens(CA=89.2, f=4278.32701, name='MCD-CAM')
ELT_DET = OpticalSurface(name='MCD-DET')
MCD = OpticalTrain()
MCD.add_object(ELT_MIRROR, dist=0)
MCD.add_object(ELT_FP, dist=ELT_MIRROR.f)
MCD.add_object(ELT_COL, dist=ELT_COL.f)
ELT_ADC.add_to_optical_train(MCD, 1209.4718)
MCD.add_object(ELT_CAM, dist=50)
MCD.add_object(ELT_DET, dist=ELT_CAM.f)
# Print lens data for verification
# MCD.print_lens_data()
###########################################################
###################### PROPAGATION ########################
###########################################################
coordinatesList = [
[-1.5, 1.5, -1.5, 1.5],
[-200, 200, -200, 200],
[-120, 120, -120, 120],
[-120, 120, -120, 120],
[-120, 120, -120, 120],
[-120, 120, -120, 120],
[-120, 120, -120, 120],
[-1.5, 1.5, -1.5, 1.5]
]
xin, yin = x, y
print('Starting propagation...')
# From ELT-M1 to ELT-FP
print('Propagating from ELT-M1 to ELT-IFP', end='\r')
wf = ELT_MASK.astype('complex128')
ELT_MIRROR.add_wavefront_error(dispersion_tilt)
wf *= ELT_MIRROR.phase_delay(x,y,l, paraxial=True)
Exyz, x, y = fou.fresnel_propagation(wf, xin, yin, dz=ELT_MIRROR.f, oversample=None,
show=False, save=False)#, outputCoordinates=coordinatesList[0], apply_interpolation=False)
# save_variable('./data/ELT_FP_{}.pkl'.format(l*1000), [Exyz, x, y])
# From ELT-FP to MCD-COL
print('Propagating from ELT-IFP to MCD-COL', end='\r')
Exyz2, x2, y2 = fou.fresnel_propagation(Exyz, x, y, dz=ELT_COL.f, oversample=None,
show=False, save=False, outputCoordinates=coordinatesList[1], apply_interpolation=False)
# From MCD-COL to MCD-ADC-P1
print('Propagating from MCD-COL to MCD-ADC-P1', end='\r')
Exyz2 *= ELT_COL.phase_delay(x2,y2,l, paraxial=True)
Exyz3, x3, y3 = fou.plane_wave_propagation(Exyz2, x2, y2, dz=MCD.sequentialDistance[3], oversample=None,
show=False, save=False, outputCoordinates=None)
# From MCD-ADC-P1 to MCD-ADC-P2
print('Propagating from MCD-ADC-P1 to MCD-ADC-P2', end='\r')
Exyz3 *= ELT_ADC.get_phase_delay(x3,y3,l, theta=None, paraxial=True, prism=1)
Exyz4, x4, y4 = fou.plane_wave_propagation(Exyz3, x3, y3, dz=MCD.sequentialDistance[4], oversample=None,
show=False, save=False, outputCoordinates=None)
# From MCD-ADC-P2 to MCD-ADC-P3
print('Propagating from MCD-ADC-P2 to MCD-ADC-P3', end='\r')
Exyz4 *= ELT_ADC.get_phase_delay(x4,y4,l, theta=None, paraxial=True, prism=2)
Exyz5, x5, y5 = fou.plane_wave_propagation(Exyz4, x4, y4, dz=MCD.sequentialDistance[5], oversample=None,
show=False, save=False, outputCoordinates=None)
# From MCD-ADC-P3 to MCD-ADC-P4
print('Propagating from MCD-ADC-P3 to MCD-ADC-P4', end='\r')
Exyz5 *= ELT_ADC.get_phase_delay(x5,y5,l, theta=None, paraxial=True, prism=3)
Exyz6, x6, y6 = fou.plane_wave_propagation(Exyz5, x5, y5, dz=MCD.sequentialDistance[6], oversample=None,
show=False, save=False, outputCoordinates=None)
# From MCD-ADC-P4 to MCD-CAM
print('Propagating from MCD-ADC-P4 to MCD-CAM', end='\r')
Exyz6 *= ELT_ADC.get_phase_delay(x6,y6,l, theta=None, paraxial=True, prism=4)
Exyz7, x7, y7 = fou.plane_wave_propagation(Exyz6, x6, y6, dz=MCD.sequentialDistance[7], oversample=None,
show=False, save=False, outputCoordinates=None)
# From MCD-CAM to MCD-DET
print('Propagating from MCD-CAM to MCD-DET', end='\r')
Exyz7 *= ELT_CAM.phase_delay(x7,y7,l, paraxial=True)
Exyz8, x8, y8 = fou.fresnel_propagation(Exyz7, x7, y7, dz=ELT_CAM.f, oversample=None,
show=False, save=False, outputCoordinates=None, apply_interpolation=False)
# The result here shifts the PSF to the side, due to the phase tilts of the ADC
# surfaces. We find the locations of the maximum and redo the the fresnel propagation
# around these coordinates.
# print('Zooming in on the PSF location...', end='\r')
# imax_1, imax_2 = find_maximum(np.abs(Exyz8))
# x8max = x8[imax_1, imax_2]
# y8max = y8[imax_1, imax_2]
# newCoordinates = np.asarray(coordinatesList[7]) + np.array([x8max, x8max, y8max, y8max])
# newCoordinates = newCoordinates.real.tolist()
# Exyz9, x9, y9 = fou.fresnel_propagation(Exyz7, x7, y7, dz=ELT_CAM.f, oversample=None,
# show=False, save=False, outputCoordinates=newCoordinates, apply_interpolation=True)
print('Propagation finished!')
Exyz_list.append(np.abs(Exyz8)**2)
fou = None
del fou
wfe = None
del wfe
MCD = None
del MCD
wf = None
del wf
ELT_MIRROR = None
del ELT_MIRROR
ELT_COL = None
del ELT_COL
ELT_ADC = None
del ELT_ADC
ELT_CAM = None
del ELT_CAM
ELT_DET = None
del ELT_DET
###########################################################
Exyz_total = np.asarray(Exyz_list).sum(axis=0)
_xip = x8
_yip = y8
# save = 'ELT-MCD-Hband_dispersion_corrected.pdf'
_fig = plt.figure()
_ax = _fig.add_subplot(111)
_im = _ax.imshow(Exyz_total.T, cmap='hot',
extent=[_xip.min(), _xip.max(), _yip.min(), _yip.max()], norm=LogNorm(vmin=2e-7))
_ax.set_xlim([_xip.min(), _xip.max()])
_ax.set_ylim([_yip.min(), _yip.max()])
_ax.set_xlabel('x [mm]')
_ax.set_ylabel('y [mm]')
_fig.colorbar(_im, ax=_ax, label='Intensity')
plt.tight_layout()
# plt.savefig(save, bbox_inches='tight', transparent=True)
plt.show()