def RMS(curv_list, image_dist): """For a singlet lens with given surface curvatures, return RMS deviation from optical axis at a given image distance of a uniformly distributed beam of rays of initial diameter 10mm.The beam propagates through the singlet lens with refractive index 1.5168 and radius aperture 50mm. Parameters: curv_list -- List of curvatures for both side of the singlet lens. The first element of the list is assigned as the curvature of the surface facing the input, and the second element is assigned as the curvature of the surface facing the output. image_dist -- Float image distance from the axial intersection of the input-facing surface to the point of desired focus. """ curv1 = curv_list[0] curv2 = curv_list[1] surface1 = rtm.SphericalRefraction([0., 0., 100.], curv1, 1., 1.5168, 50.) surface2 = rtm.SphericalRefraction([0., 0., 105.], curv2, 1.5168, 1., 50.) output = rtm.OutputPlane([0., 0., image_dist + 100.], 10000.) sq_deviation = [] for r, theta in genpolar.rtuniform(5, 5, 5): ray = rtm.Ray([r*np.cos(theta), r*np.sin(theta), 0.], [0., 0., 1.]) surface1.propagate_ray(ray) surface2.propagate_ray(ray) output.propagate_ray(ray) if ray._terminate == False: r_squared = ray.p()[0]**2. + ray.p()[1]**2. sq_deviation.append(r_squared) else: print "RAY TERMINATED\nRadius: {}mm\nAngle: {} ".format(r, theta) return None return np.sqrt(np.average(sq_deviation))
def __init__(self, nofradii=5, maxradius=5, factor=6, center=[0,0], directions=[0,0,1]): self._rays = [] for t,r in genpolar.rtuniform(n=nofradii, rmax=maxradius, m=factor): x = r*np.cos(t) y = r*np.sin(t) ray = Ray([center[0]+x, center[1]+y, 0], directions) self._rays.append(ray)
def __init__(self, nofradii=5, maxradius=5, factor=6, center=[0,0], directions=[0,0,1]): wavelengths = [0.7,0.62,0.58,0.53,0.47,0.42,0.35] self._wvdict = {'0.7':'#FF0000','0.62':'#FF7F00','0.58':'#FFFF00','0.53':'#00FF00', '0.47':'#0000FF','0.42':'#4B0082','0.35`':'#8F00FF'} self._rays = [] for t,r in genpolar.rtuniform(n=nofradii, rmax=maxradius, m=factor): x = r*np.cos(t) y = r*np.sin(t) ray = Ray([center[0]+x, center[1]+y, 0], directions, choice(wavelengths)) self._rays.append(ray)
def __init__(self, nofradii=5, maxradius=5, factor=6, center=[0, 0], directions=[0, 0, 1]): self._rays = [] for t, r in genpolar.rtuniform(n=nofradii, rmax=maxradius, m=factor): x = r * np.cos(t) y = r * np.sin(t) ray = Ray([center[0] + x, center[1] + y, 0], directions) self._rays.append(ray)
def __init__(self, p_init=[0, 0, 0], k_init=[0, 0, 1], r_spacing=5, r_max=5.0, phi_density=2, wavelength=None): if np.array_equal(np.array(k_init), np.array([0, 0, 0])) is True: raise Exception("Beam must be initialised with some direction") if len(p_init) != 3 or len(k_init) != 3: raise Exception("Beam must be initialised in 3 dimensions") self._step_num = 0 self._rays = [] self._p = [] self._k = [] k_init_norm = np.array(k_init) / np.linalg.norm(np.array(k_init)) for r, phi in gen.rtuniform(r_spacing, r_max, phi_density): x = r * np.cos(phi) + p_init[0] y = r * np.sin(phi) + p_init[1] self._rays.append(Ray([x, y, p_init[2]], k_init_norm, wavelength)) self._p.append(np.array(p_init)) self._k.append(k_init_norm)
def bundle(n=5, rmax=5, m=4, initial_z=0, direction=[0, 0, 1], x1=0, y1=0): """ The bundle function takes 5 parameters. The parameters n ,rmax and m are used when calling rtuniform. (see it's docstring for further information) The intial_z parmeter determines where the bundle of rays starts at on the z axis. The initial direction parameter determines the initial direction of the bundle of rays. The parameters x1,y1 allow the x and y coordinates to be offset. Note bundle of rays is returned as list_of_rays. """ list_of_rays = [] for r, t in gen.rtuniform(n, rmax, m): ith_ray = rt.Ray([(r * np.cos(t) + x1), (r * np.sin(t) + y1), initial_z], direction) # Creates a ray instance for each pair of r, theta coordinates. # The rays are then appended to a list. list_of_rays.append(ith_ray) return list_of_rays
def GenRays(n,rmax,m,di=[0.,0.,1.],src=[0.,0.,0.]): ''' Returns a list of rays which make up a collimated, uniform circular beam. n: number of radii (int) rmax: max radius (float) m: a measure of the number of points at each radius (int) specificially ,the number of points per circle is m*radius di: Direction of rays src: Centre ray's origin ''' rays=[] a = [i for i in gp.rtuniform(n,rmax,m)] for b in a: rays.append( Ray(array( [src[0]+b[0]*np.cos(b[1]), src[1]+b[0]*np.sin(b[1]), src[2]] ), array(di))) return rays
def __init__(self, nofradii=5, maxradius=5, factor=6, center=[0, 0], directions=[0, 0, 1]): wavelengths = [0.7, 0.62, 0.58, 0.53, 0.47, 0.42, 0.35] self._wvdict = { '0.7': '#FF0000', '0.62': '#FF7F00', '0.58': '#FFFF00', '0.53': '#00FF00', '0.47': '#0000FF', '0.42': '#4B0082', '0.35`': '#8F00FF' } self._rays = [] for t, r in genpolar.rtuniform(n=nofradii, rmax=maxradius, m=factor): x = r * np.cos(t) y = r * np.sin(t) ray = Ray([center[0] + x, center[1] + y, 0], directions, choice(wavelengths)) self._rays.append(ray)
def plotspots(a=1): """Produces three plots: 1) Spot diagram of initial bundle of rays in x-y plane. 2) Ray diagram in x-z plane showing rays passing through the lens. 3) Spot diagram of ray bundle at the output plane i.e. the detector. Produces plots for either orientation of the lens depending on a.""" if a == 1: lens1 = SR1 lens2 = SR2 else: lens1 = SR3 lens2 = SR4 x = findzintercept(lens1,lens2) focal = x[2] output = rt.OutputPlane(focal) print "Focal length for orientation %g is %g mm." % (a, focal) bundle = [] for r,t in gp.rtuniform(7, 5.0, 6): #rmax (5.0) must be a float xcoord = r*np.cos(t) ycoord = r*np.sin(t) ray = rt.Ray([xcoord,ycoord,0.0],[0.0,0.0,0.1]) lens1.propagate_ray(ray) lens2.propagate_ray(ray) output.propagate_ray(ray) bundle.append(ray) plt.figure(a) if a == 1: plt.suptitle('Planoconvex Lens Orientation 1', size=16) else: plt.suptitle('Planoconvex Lens Orientation 2', size=16) ax1 = plt.subplot(2,2,1) ax1.plot(xcoord, ycoord, 'bo') ax1.set_title('Bundle of Rays at Source, z=0', size=12) ax1.axis('equal') ax2 = plt.subplot(2,2,2) x2 = [j[2] for j in ray.vertices()] y2 = [j[0] for j in ray.vertices()] ax2.plot(x2,y2,'r-') ax2.set_title('Propagation of Rays in xz Plane', size=12) x3 = [j._p[0] for j in bundle] y3 = [j._p[1] for j in bundle] ax3 = plt.subplot(2,2,3) ax3.plot(x3,y3,'bo') ax3.set_title('Bundle of Rays at Focus', size=12) ax3.locator_params(nbins=5) ax3.axis('equal') findrms(bundle) difflim = ((588*10**(-9))*focal)/10.0 print "The diffraction limit is %g m." % difflim
sphere.propagate_ray(test_ray) test_output.propagate_ray(test_ray) p1 = test_ray.vertices()[1] p2 = test_ray.vertices()[2] gradient =((p1[0]-p2[0])/(p1[2]-p2[2])) #This is the gradient of the line equation for the ray's final path. paraxial_focus = p1[2] - p1[0]/gradient print "Paraxial Focus: {} mm ".format(paraxial_focus) output = rtm.OutputPlane([0, 0, paraxial_focus], 33) x1 = [] y1 = [] x2 = [] y2 = [] fig = plt.figure(1) ax = fig.add_subplot(111, projection='3d') for r, t in genpolar.rtuniform(10, 10, 10): x0 = [] y0 = [] z0 = [] ray = rtm.Ray([r*np.cos(t), r*np.sin(t), 0], [0, 0, 1]) x1.append(ray.p()[0]) y1.append(ray.p()[1]) sphere.propagate_ray(ray) output.propagate_ray(ray) for vector in ray.vertices(): x0.append(vector[0]) y0.append(vector[1]) z0.append(vector[2]) ax.plot(z0, x0, y0, 'ro--') x2.append(ray.p()[0]) y2.append(ray.p()[1])
for element in setup: element.propagate_ray(ray) p1 = ray.vertices()[2] p2 = ray.vertices()[3] gradient = ((p1[0] - p2[0]) / (p1[2] - p2[2])) #Finds line equation of ray's path between lens and the output plane. if gradient >= 0: print "LENS CANNOT FOCUS" paraxial_focus = p1[2] - p1[0] / gradient print "Paraxial Focus: {} mm ".format(paraxial_focus) setup[2] = rtm.OutputPlane([0, 0, paraxial_focus], 100) #Moves output to paraxial focus. sq_deviation = [] plt.figure(1) plt.subplot(1, 2, Experiments.index(setup) + 1) for r, t in genpolar.rtuniform(5, 5, 10): ray = rtm.Ray([r * np.cos(t), r * np.sin(t), 0], [0, 0, 1]) for element in setup: element.propagate_ray(ray) if ray._terminate == False: plt.plot(ray.p()[0], ray.p()[1], 'ro') sq_deviation.append(ray.p()[0]**2 + ray.p()[1]**2) plt.grid(b=None, which='both', color='c', linestyle='-', linewidth='0.4') plt.title("Spot diagram at paraxial focus") plt.xlabel("X (mm)") plt.ylabel("Y (mm)") plt.axis([-0.08, 0.08, -0.07, 0.09]) s = "Setup {}\nParaxial Focus {} mm\nRMS: {} mm \nBeam Diameter:\ 10 mm" .format(Experiments.index(setup) + 1, "%.5G"%(paraxial_focus),\ "%.5G"%np.sqrt(np.average(sq_deviation))) xy = [-0.04, 0.06]