ehpor / hcipy

A framework for performing optical propagation simulations, meant for high contrast imaging, in Python.
https://hcipy.org
MIT License
93 stars 31 forks source link

How to Correct Low Order Aberrations? #239

Closed AmitJha074 closed 2 weeks ago

AmitJha074 commented 3 weeks ago

Hi, I am pretty new to HCIPy so I would greatly appreciate any help. I'm sorry if this is not the right forum to ask for help.

Initialization

D_tel = 8 # Telescope diameter in meters wavelength = 1e-6 # Wavelength in meters

pupil_grid = make_pupil_grid(512, D_tel) aperture = circular_aperture(D_tel)(pupil_grid)

outer_scale = 20 # Outer scale of turbulence in meters velocity = 10 # Turbulence velocity in meters/sec Cn_squared = 1e-15 # Refractive index structure constant layer = InfiniteAtmosphericLayer(pupil_grid, Cn_squared, outer_scale, velocity)

Generate the turbulent wavefront

wf = Wavefront(aperture np.exp(2j np.pi pupil_grid.x 1), wavelength) turbulent_wf = layer(wf)

Convert wrapped phase to OPD

opd_aberrated = turbulent_wf.phase / (2 np.pi) wavelength

Display initial turbulent PSF

focal_grid = make_focal_grid(8, 16, reference_wavelength=wavelength, f_number=0.1) prop = FraunhoferPropagator(pupil_grid, focal_grid) img = prop(turbulent_wf) plt.figure() imshow_field(np.log10(img.intensity / img.intensity.max()), vmin=-3) plt.colorbar() plt.title("Original Aberrated PSF") plt.show()

Decompose the OPD into Zernike modes

zernike_basis = make_zernike_basis(4, D_tel, pupil_grid, starting_mode=1) # First four Zernike modes aperture_masked_opd = opd_aberrated * aperture # Apply mask to restrict within the aperture

Project onto the defocus mode (Zernike mode index 4 in Noll's ordering)

defocus_mode = zernike_basis[3] * aperture # Mode index 4 corresponds to defocus in this basis

Calculate projection of OPD onto the defocus mode

defocus_projection = np.dot(aperture_masked_opd, defocus_mode) / np.dot(defocus_mode, defocus_mode)

Remove the defocus term by subtracting it from the aberrated OPD

opd_corrected = aperture_masked_opd - defocus_projection * defocus_mode

Create the corrected wavefront with adjusted phase

phase_corrected = 2 np.pi opd_corrected / wavelength wf_corrected = Wavefront(aperture np.exp(1j phase_corrected), wavelength)

Display corrected PSF

corrected_img = prop(wf_corrected) plt.figure() imshow_field(np.log10(corrected_img.intensity / corrected_img.intensity.max()), vmin=-3) plt.colorbar() plt.title("Corrected PSF (Defocus Removed)") plt.show()

ehpor commented 2 weeks ago

I see that you closed this issue by yourself.

For reference, your problem was with the big tilt that you added. This makes the OPD itself wrap, which makes your projection of defocus on the wrapped OPD fail.

With tilt: image

Without tilt: image

# Display uncorrected and corrected OPD
corrected_img = prop(wf_corrected)
plt.figure()
plt.subplot(1,3,1)
plt.title('Original OPD')
imshow_field(aperture_masked_opd, cmap='RdBu')
plt.colorbar()
plt.subplot(1,3,2)
plt.title('Corrected OPD')
imshow_field(opd_corrected, cmap='RdBu')
plt.colorbar()
plt.subplot(1,3,3)
plt.title('Difference')
imshow_field(aperture_masked_opd - opd_corrected, cmap='RdBu')
plt.colorbar()
plt.show()