def CDAbeam(num, div, pitch, roll, cda): ## PT.transform(*cda) PT.pointsource(div, num) PT.transform(0, 0, 0, pitch, 0, 0) PT.transform(0, 0, 0, 0, 0, roll) PT.itransform(*cda) return
def traceBeam(gratAlign,order=1.,wave=2.48,blaze=30.): """Traces a beam to grating, applies misalignment, then traces to focal plane and returns mean x,y position x refers to spectral direction """ #Compute yaw to achieve Littrow configuration phi0 = arccos(sin(1.5*pi/180)/cos(blaze*pi/180)) yaw = -tan(sin(blaze*pi/180)/tan(phi0)) ## yaw = yaw - pi/2 ## pdb.set_trace() #Set up beam rays = PT.pointsource(0.,10) #multiple rays to avoid Python complaints #Rotate to nominal grating reference frame PT.transform(rays,0,0,0,pi/2+1.5*pi/180,0,0) #Apply misalignment PT.transform(rays,*gratAlign) #Trace grating PT.flat(rays) PT.transform(rays,0,0,0,0,0,yaw) #-1.73211678*pi/180 PT.radgrat(rays,11500.,160./11500.,order,wave) PT.itransform(rays,0,0,0,0,0,yaw) #Reverse misalignment PT.itransform(rays,*gratAlign) #Trace to focal plane PT.transform(rays,0,11500.,0,0,0,0) PT.transform(rays,0,0,0,pi/2,0,0) PT.flat(rays) #Return mean positions return mean(rays[1]),mean(rays[2])
def sphericalNodes(rin,z0,fov,Nshells,N): """This function will iteratively scan node positions about a sphere around the focus. Node will start in obvious vignetting position. Extreme rays will be traced including FoV. Node will be nudged outward until vignetting no longer occurs. Node will then be moved by the designated mechanical gap. Then the next node is traced in the same fashion. Assumptions: 50 mm symmetric gap """ #Bookkeeping parameters f = np.sqrt(rin**2+z0**2) fov = fov/60.*np.pi/180. #fov to radians zlist = [] rlist = [] for i in range(Nshells): #Starting radius for next shell node rstart = PT.wsPrimRad(z0+225.,1.,rin,z0) #Reduce rstart until vignetting is reached flag = 0 while flag==0: zstart = np.sqrt(f**2-rstart**2) #Set up rays r1 = PT.wsPrimRad(zstart+25.,1.,rstart,zstart) r2 = PT.wsPrimRad(zstart+225.,1.,rstart,zstart) PT.pointsource(0.,N) PT.z = np.repeat(10500.,N) PT.x = np.linspace(r1,r2,N) PT.n = np.repeat(-1.,N) #Perform trace and add FoV deflections to rays PT.wsPrimary(rstart,zstart,1.) PT.l = np.repeat(np.sin(fov),N) PT.n = -np.sqrt(1 - PT.l**2) #Verify that rays do not hit prior primary PT.wsPrimary(rin,z0,1.) if np.sum(PT.z<z0+225.) != 0: #Ray has hit print 'Ray hits prior primary!' flag = 1 #Verify that rays do not hit prior secondary PT.wsPrimary(rstart,zstart,1.) PT.reflect() PT.wsSecondary(rstart,zstart,1.) PT.reflect() PT.wsSecondary(rin,z0,1.) if np.sum(PT.z > z0-225.) != 0: print 'Ray hits prior secondary!' flag = 1 #Look at other deflection PT.pointsource(0.,N) PT.z = np.repeat(10500.,N) PT.x = np.linspace(r1,r2,N) PT.n = np.repeat(-1.,N) #Perform trace and add FoV deflections to rays PT.wsPrimary(rstart,zstart,1.) PT.l = np.repeat(-np.sin(fov),N) PT.n = -np.sqrt(1 - PT.l**2) #Verify that rays do not hit prior primary PT.wsPrimary(rin,z0,1.) if np.sum(PT.z<z0+225.) != 0: #Ray has hit print 'Ray hits prior primary!' flag = 1 #Verify that rays do not hit prior secondary PT.wsPrimary(rstart,zstart,1.) PT.reflect() PT.wsSecondary(rstart,zstart,1.) PT.reflect() PT.wsSecondary(rin,z0,1.) if np.sum(PT.z > z0-225.) != 0: print 'Ray hits prior secondary!' flag = 1 if flag==0: rstart = rstart - .01 #Take off 10 microns ## sys.stdout.write(str(rstart)+'\n') ## sys.stdout.flush() #Vignetting has been reached, append rstart and zstart #to list of node positions rlist.append(rstart) zlist.append(zstart) rin = rstart z0 = zstart return rlist,zlist