-
Notifications
You must be signed in to change notification settings - Fork 59
Description
Hello, @FredvanGoor
I am simulating the calculation of a circular aperture beam passing through a lens and converging at the focal plane. I want to calculate what is the radius of the spot when the energy in the barrel at the focal plane is 83.9%. And calculate its times of the diffraction limit.
If the diameter of the center of the first dark ring (Airy disk) of a Fraunhofer diffraction pattern is taken as the diffraction limit diameter.Theoretically, When focused through an ideal lens to the focal plane, the measured ideal diffraction limit diameter should be
Formula 1
According to Formula 1, it can be calculated that
There are some details for $u_{ref}$
According to Fraunhofer diffraction theory, the far-field intensity distribution of the reference beam with radius
Let
According to Formula 1, when
So the calculation result we would expect should be
But in practice, the code didn't work as I thought it would.
Code Parts
At first, I tried combining the Lens() and Propagate() functions.
Then ,I tried LensFarfield() Fuction
And now,I am trying use Spherical coordinates
calRediuswithPow.py is the base function I used to calculate it, there are some things wrong with its algorithm, such as the center of mass calculating itself, and the energy calculating itself, but I don't think it's going to be particularly wrong for the same field and it's propagation, and during debugging, the energy percentage was not more than 0.3% wrong
They all produce beta results that are way off compared to one, generally speaking aspherical coordinate calculations will be about 30% off, and will change greatly with focal length, and diameter of the circular hole,even if I use "ideal sampling":
I'm not sure what went wrong, the radius calculations should not logically produce such a large deviation. Is there something I am not taking into account in my simulation method.
calRediuswithPow.py
use calRediuswithPow() function to calculate the radius corresponding to energy in specify bucket
from LightPipes import *
import matplotlib as mpl
import numpy as np
import copy as _copy
def calRediuswithPow(fieldIn,energyPercent=0.839):
'''
Calculate the radius corresponding to the ring energy
Parameters
----------
energyPercent : double
fieldIn : lp.Field
The input field.
Returns
-------
The Redius correspend to the energyPercent power.
"""
----------
'''
fieldIn=_copy.copy(fieldIn)
I=Intensity(fieldIn)
sumEnergy=0
# sumEnergy=sum(I)
sumEnergy1=0
sumEnergy1=0
F_row=np.size(fieldIn.field,0)
F_col=np.size(fieldIn.field,1)
for i in range(F_row):
for j in range(F_col):
sumEnergy+=I[i][j]
#sumEnergy2=Power(fieldIn)
targetEnergy=energyPercent*sumEnergy
# Y, X = fieldIn.mgrid_cartesian
#Determine spot center of mass Coordinate system with array indexed x,y coordinates
x_power_sum=0
y_power_sum=0
for i in range(F_row):
for j in range(F_col):
x_power_sum+=I[i][j]*i
for i in range(F_row):
for j in range(F_col):
y_power_sum+=I[i][j]*j
x_center=x_power_sum/sumEnergy
y_center=y_power_sum/sumEnergy
#Calculate the approximation of the true radius using the Bisection method.
# First set the maximum value of the radius to the diagonal of the matrix
r_max=np.sqrt(F_row**2+F_col**2)
r_min=0
girdR=binarySearchR(I,r_max,r_min,targetEnergy,x_center,y_center,F_row,F_col)
Rres=girdR*fieldIn.dx
return Rres
def binarySearchR(intensityIn,r_max,r_min,targetEnergy,x_center,y_center,F_row,F_col):
'''
Bisection method to approximate the real radius (the fitting effect is a bit poor, later can be changed to a point by point cascade outward expansion)
The error is close to 0.3%
'''
while r_min <= r_max:
r_mid=(r_min+(r_max-r_min)/2)
midEnergy=calPowerWithRadius(intensityIn,F_row,F_col,x_center,y_center,r_mid)
if midEnergy == targetEnergy:
return r_mid
elif midEnergy>targetEnergy:
r_max=r_mid-1
else:
r_min=r_mid+1
#close
return r_mid
#TODO:Sort, compute distance from center of mass for all cells, put into set sort, set map
def calPowerWithRadius(intensityIn,F_row,F_col,x_center,y_center,radius):
'''
Calculate the power within a specified radius
'''
powerRes=0
for i in range(F_row):
for j in range(F_col):
if ((i-x_center)**2+(j-y_center)**2)<=radius**2:
powerRes+=intensityIn[i][j]
return powerRes LensAndLensFarfieldTry.py
try combine Lens() and Propagate() And try LensFarfield()
from LightPipes import *
import matplotlib as mpl
import numpy as np
import calRediuswithPow
mpl.use('TkAgg')
import matplotlib.pyplot as plt
#import Utils
# wavelength = 500*nm
# size = 7*mm
# N = 100
# w0 = 1*mm
# f = 1*m
# z = 1*m
wavelength = 1000 * nm
N = 3000 #2840
size = 125 * mm
f = 5.5*m
z = f
w0 = 1*mm
# dx = wavelength*z/size
# N = int(size/dx)
F = Begin(size, wavelength, N)
F= CircAperture(R=50*mm,Fin=F)
F = Lens(F, f)
# F = Fresnel(F, z)
# F = Forvard(F, z)
F = Propagate(F, f)
# F2=LensFresnel(f2,f,F2);
# F=LensFarField(F,f)
# F=Forward(F)
#############################Beita calculate start###############################################
d = 100*mm
FToCalB=F
Dpow=calRediuswithPow.calRediuswithPow(FToCalB,0.839)*2
DTherory=2.44*FToCalB.lam*f/d
beita=Dpow/DTherory
print('The Beita is :',beita)
#############################Beita calculate end###############################################TrySphericalCoordinates.py
Try use Spherical Coordinatesto calculate
from LightPipes import *
import matplotlib.pyplot as plt
#import Utils
import calRediuswithPow
def TheExample(N):
fig = plt.figure(figsize=(15, 9.5))
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax4 = fig.add_subplot(224)
labda = 1000 * nm
size = 10 * mm
f = 100 * cm
f1 = 10 * m
f2 = f1 * f / (f1 - f)
frac = f / f1
newsize = frac * size
w = 10 * mm
w=w/5
#something wrong#########################################
# wavelength = 1000 * nm
# # N = 500
# size = 125 * mm
# f = 500 * mm
# z = 500 * mm
# w0 = 1 * mm
############################################
F = Begin(size, labda, N)
F = CircAperture(F, R=w)
# 1) Using Lens and Fresnel:
F1 = Lens(f, 0, 0, F)
# F1 = Fresnel(f, F1)
F1 = Propagate(F1,f)
phi1 = Phase(F1)
phi1 = PhaseUnwrap(phi1)
I1 = Intensity(0, F1)
x1 = []
for i in range(N):
x1.append((-size / 2 + i * size / N) / mm)
# 2) Using Lens + LensFresnel and Convert:
F2 = Lens(f1, 0, 0, F)
F2 = LensFresnel(f2, f, F2)
F2 = Convert(F2)
phi2 = Phase(F2)
phi2 = PhaseUnwrap(phi2)
I2 = Intensity(0, F2)
#Utils.show(F2,"F2 Inten")
x2 = []
for i in range(N):
x2.append((-newsize / 2 + i * newsize / N) / mm)
ax1.plot(x1, phi1[int(N / 2)], 'k--', label='Without spherical coordinates')
ax1.plot(x2, phi2[int(N / 2)], 'k', label='With spherical coordinates')
ax1.set_xlim(-newsize / 2 / mm, newsize / 2 / mm)
ax1.set_ylim(-2, 4)
ax1.set_xlabel('x [mm]')
ax1.set_ylabel('phase [rad]')
ax1.set_title('phase, N = %d' % N)
legend = ax1.legend(loc='upper center', shadow=True)
ax2.plot(x1, I1[int(N / 2)], 'k--', label='Without spherical coordinates')
ax2.plot(x2, I2[int(N / 2)], 'k', label='With spherical coordinates')
ax2.set_xlim(-newsize / 2 / mm, newsize / 2 / mm)
ax2.set_ylim(0, 1000)
ax2.set_xlabel('x [mm]')
ax2.set_ylabel('Intensity [a.u.]')
ax2.set_title('intensity, N = %d' % N)
legend = ax2.legend(loc='upper center', shadow=True)
ax3.imshow(I1)
ax3.axis('off')
ax3.set_title('Without spherical coordinates')
ax3.set_xlim(int(N / 2) - N * frac / 2, int(N / 2) + N * frac / 2)
ax3.set_ylim(int(N / 2) - N * frac / 2, int(N / 2) + N * frac / 2)
ax4.imshow(I2)
ax4.axis('off')
ax4.set_title('With spherical coordinates')
plt.figtext(0.3, 0.95, 'Spherical Coordinates, f = 100cm lens\nGrid dimension is: %d x %d pixels' % (N, N),
fontsize=18, color='red')
#############################Beita calculate start###############################################
d = w
FToCalB=F2
Dpow=calRediuswithPow.calRediuswithPow(FToCalB,0.839)*2
DTherory=2.44*FToCalB.lam*f/d
beita=Dpow/DTherory
print('The Beita is :',beita)
#############################Beita calculate end###############################################
# TheExample(100) # 100 x 100 grid
TheExample(1000) # 1000 x 1000 grid
plt.show()Others
Spherical coordinates is a little hard to understand, for example I don't know how to set f1 and z. @ldoyle 's xplanation confused me even more
End
Thanks for your reading!
I've been puzzling over these calculations for a long time, so if you have time please help me!
References
[1] Hecht E. Optics[M]. 5.Boston: Pearson Education, Inc.,2017: vi, 480-484.
[2] Voelz D G.Computational fourier optics: a MATLAB tutorial[J],2011.