mirror of
https://github.com/yosata/fourierOptics.git
synced 2026-10-30 05:01:04 +00:00
160 lines
6.0 KiB
Python
160 lines
6.0 KiB
Python
import numpy as np
|
|
import os
|
|
import sys
|
|
sys.path.insert(0, '/Users/joost/Dropbox/Werk/PhD/Documents/Published/FourierOptics GitHub release/')
|
|
from fourierOptics import *
|
|
|
|
'''
|
|
Author: Joost van den Born, PhD student at University of Groningen
|
|
Contact: born@astro.rug.nl
|
|
Description: Script to compare the Strehl ratio of 50 different instances
|
|
of a generated WFE. Higher spatial frequency perturbations
|
|
should follow the Marechal approximation more closely than
|
|
lower order shape errors only. We verify this using Power
|
|
Spectral Density and Zernike modes (66 coefficients).
|
|
Script made for the SPIE manuscript.
|
|
'''
|
|
|
|
|
|
def expected_strehl2(rms, l):
|
|
return np.exp( -(2*np.pi*rms/l)**2 )
|
|
|
|
|
|
def append_to_existing_data(A, filename):
|
|
if os.path.exists(filename):
|
|
A_o = load_variable(filename)
|
|
A2 = np.append(A, A_o)
|
|
else:
|
|
A2 = A
|
|
return A2
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# Setting some input parameters
|
|
dpix = 160
|
|
n, m = 1001, 1001
|
|
l = 1.49e-3 # wavelength
|
|
zern_rms = 25e-5 # RMS of the zernike component of the WFE
|
|
midspat_rms = 25e-5 # RMS of the PSD component of the WFE
|
|
rmsList = np.linspace(1e-6, 1e-3, 25) # 1 to 1000 nm WFE RMS in mm
|
|
number_of_iterations = 50
|
|
input_field_location = './data/ADC_input_field_1001x1001_1.49_onaxis_obscured.pkl'
|
|
|
|
|
|
# Initiate ELT-MICADO and wavefront error objects
|
|
mcd = ParaxialMICADO(l=l, n=n, m=m, dpix=dpix, entrance_pupil='open')
|
|
wfe = WavefrontError(n,m)
|
|
|
|
print ('Your resolution is {}x{} with a pixel size of {}'.format(n,m,dpix))
|
|
|
|
# Propagate unperturbed field
|
|
E, x, y = mcd.propagate(l=l,surface=-1, zoom=False, show=False,
|
|
print_progress=False, hx=0, hy=0,
|
|
load_up_to_adc=input_field_location)
|
|
|
|
# Initiate psf fitter object to calculate the strehl ratios
|
|
psf = PSFFitter(x, y, E)
|
|
|
|
# Create some empty lists for later
|
|
strehl_zern_complete, strehl_psd_complete = [], []
|
|
rms_zern_list_complete, rms_psd_list_complete = [], []
|
|
|
|
|
|
# Repeat the analysis 50 times
|
|
for i in range(number_of_iterations):
|
|
|
|
print('Iteration {}/{}'.format(i+1,number_of_iterations))
|
|
|
|
# Generate a PSD surface
|
|
psd_surface = wfe.generate_height_map(midspat_rms, 2, 1)
|
|
|
|
# Fit the PSD surface using zernike terms
|
|
# Generating a normalized grid for the Zernike evaluation
|
|
yz,xz = np.mgrid[-1:1:wfe.n*1j, -1:1:wfe.m*1j]
|
|
_r = np.sqrt(xz**2 + yz**2)
|
|
_mask = _r > 1
|
|
coeffic = wfe.fit_zernike_coefficients(psd_surface, modes=66)
|
|
|
|
StrehlList_zern, StrehlList_psd = [], []
|
|
rms_zern_list, rms_psd_list = [], []
|
|
|
|
|
|
# Compare results at different RMS values
|
|
for rms in rmsList:
|
|
|
|
########################################
|
|
# WFE described by Zernike polynomials #
|
|
########################################
|
|
# Make a new perturbed wavefront error with the required RMS
|
|
coeffic = wfe.scale_zernike_coefficients(coeffic, rms)
|
|
hzern = wfe.zernike_cartesian(coeffic, xz, yz)
|
|
|
|
# Add the new wavefront error
|
|
mcd.ELT_ADC.p1.add_wavefront_error(hzern)
|
|
|
|
# Performing the propagation using Fresnel approximation to the focal plane.
|
|
Exyz_zern,xzern,yzern = mcd.propagate(l=l,surface=-1, zoom=False, show=False,
|
|
print_progress=False, hx=0, hy=0,
|
|
load_up_to_adc=input_field_location)
|
|
Strehl_zern = np.abs(psf.get_coupling(E, Exyz_zern))**2
|
|
StrehlList_zern.append(Strehl_zern)
|
|
########################################
|
|
|
|
|
|
########################################
|
|
# WFE described by PSD profile #
|
|
########################################
|
|
factor = rms / midspat_rms
|
|
h_psd = wfe.scale_rms(factor, data=psd_surface)
|
|
|
|
# Add the new wavefront error
|
|
mcd.ELT_ADC.p1.add_wavefront_error(h_psd)
|
|
|
|
# Performing the propagation using Fresnel approximation to the focal plane.
|
|
Exyz_psd,xpsd,ypsd = mcd.propagate(l=l,surface=-1, zoom=False, show=False,
|
|
print_progress=False, hx=0, hy=0,
|
|
load_up_to_adc=input_field_location)
|
|
Strehl_psd = np.abs(psf.get_coupling(E, Exyz_psd))**2
|
|
StrehlList_psd.append(Strehl_psd)
|
|
########################################
|
|
|
|
# Find the RMS value of the wavefront errros
|
|
rms_zern = np.sqrt(np.mean(np.asarray(hzern[~_mask])**2))
|
|
rms_psd = np.sqrt(np.mean(np.asarray(h_psd)**2))
|
|
rms_zern_list.append(rms_zern)
|
|
rms_psd_list.append(rms_psd)
|
|
|
|
# Print results
|
|
print('RMS: {:.3f}, S_zern: {:.3f}, S_psd: {:.3f}, \
|
|
RMS_zern: {:.3f}, RMS_psd: {:.3f}'.format(
|
|
rms*1e6, Strehl_zern, Strehl_psd, rms_zern*1e6, rms_psd*1e6))
|
|
|
|
|
|
# Put the results in the correct list
|
|
strehl_zern_complete.append(StrehlList_zern)
|
|
strehl_psd_complete.append(StrehlList_psd)
|
|
rms_zern_list_complete.append(rms_zern_list)
|
|
rms_psd_list_complete.append(rms_psd_list)
|
|
|
|
rms_zern_list_complete = np.asarray(rms_zern_list_complete)
|
|
rms_psd_list_complete = np.asarray(rms_psd_list_complete)
|
|
|
|
# Import old results if they are available and append them to the results.
|
|
rmsList_present = rmsList.copy()
|
|
rmsList = append_to_existing_data(rmsList, './data/SR_RMS_values_obscured.pkl')
|
|
strehl_zern_complete = append_to_existing_data(strehl_zern_complete, './data/SR_strehl_zern_obscured.pkl')
|
|
strehl_psd_complete = append_to_existing_data(strehl_psd_complete, './data/SR_strehl_psd_obscured.pkl')
|
|
rms_zern_list_complete = append_to_existing_data(rms_zern_list_complete, './data/SR_rms_zern_complete_obscured.pkl')
|
|
rms_psd_list_complete = append_to_existing_data(rms_psd_list_complete, './data/SR_rms_psd_complete_obscured.pkl')
|
|
|
|
mean_strehl_zern = np.mean(strehl_zern_complete, axis=0)
|
|
err_strehl_zern = np.std(strehl_zern_complete, axis=0)
|
|
mean_strehl_psd = np.mean(strehl_psd_complete, axis=0)
|
|
err_strehl_psd = np.std(strehl_psd_complete, axis=0)
|
|
|
|
save_variable('./data/SR_RMS_values_obscured.pkl', rmsList)
|
|
save_variable('./data/SR_strehl_zern_obscured.pkl', strehl_zern_complete)
|
|
save_variable('./data/SR_strehl_psd_obscured.pkl', strehl_psd_complete)
|
|
save_variable('./data/SR_rms_zern_complete_obscured.pkl', rms_zern_list_complete)
|
|
save_variable('./data/SR_rms_psd_complete_obscured.pkl', rms_psd_list_complete)
|