ehpor / hcipy

A framework for performing optical propagation simulations, meant for high contrast imaging, in Python.

Home Page:https://hcipy.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

fourier_transform not working as expected?

samwalker2312 opened this issue · comments

Hi,

I've just been running some simple tests with the fourier_transform class, and it seems that the Fourier transform is not invertible - i.e. fourier_transform.forward(fourier_transform.backward(x)) =/= x. Is this by design? I would have thought that this would not be the desired behaviour.

Here is a small snippet of code that can be used to illustrate this issue. As you can see from the images attached, I would expect Figure 3 to appear like Figure 1, but instead it seems identical to Figure 2 just on a different-sized grid.

import numpy as np
import matplotlib.pyplot as plt
from hcipy import *

pupilsize = 128
focalsize = 128
diameter = 12
mas_pix = 10
rad_pix = np.radians(mas_pix / 1000 / 3600)
wavelength = 1630e-9

#makes grids
pupil_grid = make_pupil_grid(pupilsize, diameter)
focal_grid = make_uniform_grid([focalsize,focalsize], [focalsize*rad_pix, focalsize*rad_pix])

#makes ft
fouriertransform = make_fourier_transform(pupil_grid, focal_grid)

#makes object to FT
c_e = LyotCoronagraph(pupil_grid, 1 - evaluate_supersampled(circular_aperture(2*wavelength/diameter), focal_grid, 8))
ce = c_e.focal_plane_mask._apodization

#computes and displays FTs
plt.figure()
imshow_field(ce)
backce = fouriertransform.backward(ce)
plt.figure()
imshow_field(backce)
forwardce = fouriertransform.forward(backce)
plt.figure()
imshow_field(forwardce)
plt.show()

Outputs:

err_fig1
err_fig2
err_fig3

Could you explain this behaviour? I would really appreciate some assistance on this, my confusion on this issue has really been putting a spanner in my research.

Thanks!

By design, a Fourier transform is invertible, but only if you calculate it on the full domain at the right frequencies (ie. in cases where the Fourier transform is equivalent to a fast Fourier transform). If you're not, you are effectively applying a filter in the Fourier domain.

It is the latter that your doing here. In your case, the extent of your real space is (by far) not large enough to accommodate lowest frequency in your Fourier domain. That way, you're essentially applying a low pass filter on your FPM image, which totally washes out the central dot. So this is totally expected for your chosen sampling. I've modified your code to show the difference between these two cases: your sampling vs an FFT sampling of the real space grid.

import numpy as np
import matplotlib.pyplot as plt
from hcipy import *

pupilsize = 128
focalsize = 128
diameter = 12
mas_pix = 10
rad_pix = np.radians(mas_pix / 1000 / 3600)
wavelength = 1630e-9

#makes grids
pupil_grid = make_pupil_grid(pupilsize, diameter)
focal_grid = make_uniform_grid([focalsize,focalsize], [focalsize*rad_pix, focalsize*rad_pix])

#makes ft
fouriertransform = make_fourier_transform(pupil_grid, focal_grid)
fouriertransform2 = make_fourier_transform(make_fft_grid(focal_grid), focal_grid)

#makes object to FT
c_e = LyotCoronagraph(pupil_grid, 1 - evaluate_supersampled(circular_aperture(2*wavelength/diameter), focal_grid, 8))
ce = c_e.focal_plane_mask._apodization

#computes and displays FTs
plt.figure()
plt.suptitle('fourier domain')
imshow_field(ce)

backce = fouriertransform.backward(ce)
forwardce = fouriertransform.forward(backce)

plt.figure()
plt.suptitle('wrong sampling')
plt.subplot(1,2,1)
plt.title('real domain')
imshow_field(backce)
plt.subplot(1,2,2)
plt.title('transformed back to fourier domain')
imshow_field(forwardce)

backce = fouriertransform2.backward(ce)
forwardce = fouriertransform2.forward(backce)

plt.figure()
plt.suptitle('right sampling')
plt.subplot(1,2,1)
plt.title('real domain')
imshow_field(backce)
plt.subplot(1,2,2)
plt.title('transformed back to fourier domain')
imshow_field(forwardce)

plt.show()

And the output plots:
image

image

image
You can clearly see the difference in extent of the real space grid (look at the numbers on the axis for the lhs subplots) between your sampling and the correct FFT sampling.