In this example we will simulate a simple autocolimator system.
The autocolimator system will be made of a point source (R), a beam splitting cube (BS), a colimator lens (L), and a CCD (C).
In this first example, this will be used to check if a mirror (M1) is parallel to the optical axis.
In [ ]:
from pyoptools.all import *
from numpy import pi
In [ ]:
R=point_source_c(span=(0.06,0.06),num_rays=(5,5),wavelength=.65)
BS=BeamSplittingCube(size=25,reflectivity=.5,material=material.schott["BK7"])
L=library.Edmund.get("32494")
C=CCD()
M1= RectMirror(size=(25, 25, 5),material=material.schott["BK7"], reflectivity=1.)
S=System(complist=[(C,(20,0,20),(0,pi/2,0)),(BS,(0,0,20),(0,0,0)),(L,(0,0,158.5),(0,-pi,0)),(M1,(0,0,170),(0,0,0))],n=1.)
S.ray_add(R)
S.propagate()
In [ ]:
Plot3D(S,center=(0,0,300), size=(600,100),scale=2,rot=[(0,0,-3*pi/8),(0,3*pi/8,0)])
In this example, the ray trace proceesd as follow:
From the interactive raytrace plot, one can get an idea about what is going on, but most of the time we need to see how the ray intersect a surface. In this case, we can get an spot diagram from the CCD as shown in the next plot.
In [ ]:
%pylab inline
spot_diagram(C)
If the lens was ideal, and the distance between the lens and the point source was adequatelly adjusted, the spot diagram would show all the 25 rays hitting at exact the same coordinates in the CCD. But as we are simulating a "real" doublet, we have a cube that introduces some spherical aberration in the path, and the distance was optimized in .5 mm steps, we get a spot in the CCD that is about 20 um in diameter, but as expected the center of such spot is the (0mm, 0mm) coordinate f the CCD.
In the next example the mirror will be tilted 10 urads
In [ ]:
R=point_source_c(span=(0.06,0.06),num_rays=(5,5),wavelength=.65)
BS=BeamSplittingCube(size=25,reflectivity=.5,material=material.schott["BK7"])
L=library.Edmund.get("32494")
C=CCD()
M1= RectMirror(size=(25, 25, 5),material=material.schott["BK7"], reflectivity=1.)
S=System(complist=[(C,(20,0,20),(0,pi/2,0)),(BS,(0,0,20),(0,0,0)),(L,(0,0,158.5),(0,-pi,0)),(M1,(0,0,170),(10.E-6,0,0))],n=1.)
S.ray_add(R)
S.propagate()
spot_diagram(C)
In this case we see that the spot is hitting the CCD approximatelly at (0mm, 0.0025 mm).
Some times getting an aproximate position of the center of the spot from a plot is not enough. In such cases we can use the hit_list property from the CCD. From this list we can get the intersection point of each ray and for example use the average in X and in Y to estimate the spot centroid position.
In [ ]:
cx=0.
cy=0.
for c,r in C.hit_list:
cx=cx+c[0]
cy=cy+c[1]
cx=cx/25
cy=cy/25
print("CMX",cx,"CMY",cy)
In this case, the resulting spot diagram is similar to the previous one, but we can see the central spot is not located at the origin of the CCD anymore, but at the coordinate (0 mm, 0.003 mm)
In the ideal case, taking in to account the reported focal lenght of the lens, and the tilting of the mirror, the coorditates of the point should be
In [ ]:
f=150.
alpha=10e-6
cy_=f*2.*alpha
print("CMY-Estimated",cy_)
As we can see, the estimated value correspond very well with the simulation.