def find_ppp(opsys, opaxis): """Function to find the primary principal plane location of a lens or an optical component Arguments: opsys Optical system or optical component whose principal planes are to be found opaxis Ray defining the optical axis of the system For this function to operate, the system should have a rotational symetry around the optical axis. Note: This function is returns the intersection point of the optical axis and the principal plane. """ # Create a system with the component if isinstance(opsys, (Component)): c = opsys opsys = System(complist=[(c, (0, 0, 0), (0, 0, 0))], n=1) # To create a ray parallel to the optical axis, find a displacement vector # perpendicular to the optical axis, and to the XYZ axes d = opaxis.dir pv1 = cross(d, (0, 0, 1)) pv2 = cross(d, (0, 1, 0)) pv3 = cross(d, (1, 0, 0)) pv = [pv1, pv2, pv3] # Search for the longest pv pvn = array((dot(pv1, pv1), dot(pv2, pv2), dot(pv3, pv3))) pvm = pv[pvn.argmax()] # Create parallel ray par_ray = opaxis.copy() par_ray.pos = par_ray.pos + pvm * 0.0001 opsys.clear_ray_list() opsys.ray_add([opaxis, par_ray]) opsys.propagate() par_ray_end = par_ray.get_final_rays(inc_zeros=False) if len(par_ray_end) != 1: raise Exception, "The paraxial ray has more than one final ray" pppl = intersection(par_ray, par_ray_end[0]) # Move the intersection point toward the optical axis ppp = pppl[0] - pvm * 0.0001 return ppp # , pppl[1])
def get_optical_path_ep(opsys, opaxis, raylist, stop=None, r=None): """Returns the optical path traveled by a ray up to the exit pupil The optical path is measured from the ray origin until it crosses the exit pupil of the system. If a stop (aperture) is not given, the measurement is made up to the primary principal plane. Arguments: opsys Optical system under analisis opaxis Ray indicating the optical axis the origin of the optical axis, must be the position of the object used in the image formation. This is needed to be able to calculate the radius of the reference sphere. raylist List of rays that will be used to sample the optical path stop Aperture stop of the system. It must belong to opsys. In not given it will be assumed that the exit pupil is at the primary principal plane. r If None, measure up to the exit pupil plane. If given, use a reference sphere with a vertex coinciding with the optical vertex. Return Value (hcl,opl,pc) hcl List containing the coordinates of the hits in the pupil coordinate system. opl list containing the optical paths measured pc intersection point between the optical axis, and the pupil plane. hcl[i] corresponds to opl[i] Note: This method only works if the optical axis coincides with the Z axis. This must be corrected. """ if stop != None: enp, exp = pupil_location(opsys, stop, opaxis) else: exp = find_ppp(opsys, opaxis) #Reset the system opsys.clear_ray_list() opsys.reset() # Propagate the rays #print "***", raylist opsys.ray_add(raylist) opsys.propagate() #pf=PlotFrame(opsys=opsys) rl = [] l = [] # Get the optical path up to the final element in the system for i in raylist: a = i.get_final_rays() if a[0].intensity != 0: # Reverse the rays to calculate the optical path from the final element #to the exit pupil nray = a[0].reverse() rl.append(nray) #TODO: This should not be done using the label nray.label = str(a[0].optical_path_parent()) # Create a dummy system to calculate the wavefront at the exit pupil if r == None: #TODO: This ccd should be infinitely big. Have to see how this can be done ccd = CCD(size=(1000, 1000)) else: ccds = Spherical(shape=Circular(radius=0.9 * r), curvature=1. / r) ccd = Component(surflist=[ (ccds, (0, 0, 0), (0, 0, 0)), ]) #print rl dummy = System(complist=[ (ccd, exp, (0, 0, 0)), ], n=1.) #Calculate the optical path from the final element to the exit pupil plane dummy.ray_add(rl) dummy.propagate() #PlotFrame(opsys=dummy) hcl = [] opl = [] for ip, r in ccd.hit_list: #print ip x, y, z = ip #TODO: This should not be done using the label d = float(r.label) - r.optical_path() hcl.append((x, y, z)) opl.append(d) return (hcl, opl, exp)
def find_ppp(opsys, opaxis): """Function to find the primary principal plane location of a lens or an optical component Arguments: opsys Optical system or optical component whose principal planes are to be found opaxis Ray defining the optical axis of the system For this function to operate, the system should have a rotational symmetry around the optical axis. Note: This function is returns the intersection point of the optical axis and the principal plane. """ # Create a system with the component if isinstance(opsys, (Component)): c = opsys opsys = System(complist=[ (c, (0, 0, 0), (0, 0, 0)), ], n=1) # To create a ray parallel to the optical axis, find a displacement vector # perpendicular to the optical axis, and to the XYZ axes d = opaxis.dir pv1 = cross(d, (0, 0, 1)) pv2 = cross(d, (0, 1, 0)) pv3 = cross(d, (1, 0, 0)) pv = [pv1, pv2, pv3] # Search for the longest pv pvn = array((dot(pv1, pv1), dot(pv2, pv2), dot(pv3, pv3))) pvm = pv[pvn.argmax()] # Create parallel ray par_ray = opaxis.copy() par_ray.pos = par_ray.pos + pvm * .0001 opsys.clear_ray_list() opsys.ray_add([opaxis, par_ray]) opsys.propagate() par_ray_end = par_ray.get_final_rays(inc_zeros=False) if len(par_ray_end) != 1: raise Exception("The paraxial ray has more than one final ray") pppl = intersection(par_ray, par_ray_end[0]) #Move the intersection point toward the optical axis ppp = pppl[0] - pvm * .0001 return ppp #, pppl[1])
def get_optical_path_ep(opsys, opaxis, raylist, stop=None, r=None): """Returns the optical path traveled by a ray up to the exit pupil The optical path is measured from the ray origin until it crosses the exit pupil of the system. If a stop (aperture) is not given, the measurement is made up to the primary principal plane. Arguments: opsys Optical system under analisis opaxis Ray indicating the optical axis the origin of the optical axis, must be the position of the object used in the image formation. This is needed to be able to calculate the radius of the reference sphere. raylist List of rays that will be used to sample the optical path stop Aperture stop of the system. It must belong to opsys. In not given it will be assumed that the exit pupil is at the primary principal plane. r If None, measure up to the exit pupil plane. If given, use a reference sphere with a vertex coinciding with the optical vertex. Return Value (hcl,opl,pc) hcl List containing the coordinates of the hits in the pupil coordinate system. opl list containing the optical paths measured pc intersection point between the optical axis, and the pupil plane. hcl[i] corresponds to opl[i] Note: This method only works if the optical axis coincides with the Z axis. This must be corrected. """ if stop != None: enp,exp=pupil_location(opsys,stop,opaxis) else: exp= find_ppp(opsys, opaxis) #Reset the system opsys.clear_ray_list() opsys.reset() # Propagate the rays #print "***", raylist opsys.ray_add(raylist) opsys.propagate() #pf=PlotFrame(opsys=opsys) rl=[] l=[] # Get the optical path up to the final element in the system for i in raylist: a=i.get_final_rays() if a[0].intensity!=0: # Reverse the rays to calculate the optical path from the final element #to the exit pupil nray=a[0].reverse() rl.append(nray) #TODO: This should not be done using the label nray.label=str(a[0].optical_path_parent()) # Create a dummy system to calculate the wavefront at the exit pupil if r==None: #TODO: This ccd should be infinitely big. Have to see how this can be done ccd=CCD(size=(1000,1000)) else: ccds=Spherical(shape=Circular(radius=0.9*r), curvature=1./r) ccd=Component(surflist=[(ccds, (0, 0, 0), (0, 0, 0)), ]) #print rl dummy=System(complist=[(ccd,exp,(0,0,0)), ],n=1.) #Calculate the optical path from the final element to the exit pupil plane dummy.ray_add(rl) dummy.propagate() #PlotFrame(opsys=dummy) hcl=[] opl=[] for ip,r in ccd.hit_list: #print ip x,y,z= ip #TODO: This should not be done using the label d= float(r.label)-r.optical_path() hcl.append((x, y, z)) opl.append(d) return (hcl, opl, exp)
#~ print 'Saved image to %s'% (os.path.abspath( filename)) #~ return image return Image(data,embed=True) if __name__ == "__main__": from pyoptools.all import * # Blue r_b= parallel_beam_c(size=(10,10),num_rays=(10,10), wavelength=.470) N_BK7=schott['BK7'] bs=BeamSplitingCube(size=50,material=N_BK7,reflectivity=0.5) #Definition of a detector plane ccd=CCD(size=(20, 20)) os=System(complist=[(bs,(0,0,50),(0,0,0)), (ccd,(0,0,100),(0,0,0)), ],n=1) #Add the ray sources os.ray_add(r_b) #Propagate the rays os.propagate() app = wx.PySimpleApp(0) wx.InitAllImageHandlers() oglFrame = glPlotFrame2(os) app.SetTopWindow(oglFrame) oglFrame.Show() app.MainLoop()