def findGratingPosition(N, hubdist=11832.911, order=1, wave=4.4, disp=0.): """Place the SPO pair, find the focus, and then go back up to grating placement """ #Set up SPO rays = traceSource(N) placeSPO(rays) #SPO intersection plane is global coordinate system #Go to focus gratc = [tran.tr.identity_matrix()] * 4 surf.focusI(rays, coords=gratc) #Go back up to grating point tran.transform(rays, 0, 0, np.mean(-11828.856 * rays[6]), 0, 0, 0, coords=gratc) surf.flat(rays) #Place grating #Get to XY centroid of beam, now at center of grating tran.transform(rays, np.mean(rays[1]), 0, 0, 0, 0, 0, coords=gratc) gratc2 = np.copy(gratc) #Rotate to proper incidence angle tran.steerX(rays, coords=gratc2) tran.transform(rays, 0, 0, 0, 0, pi / 2 - 1.5 * pi / 180, 0, coords=gratc2) surf.flat(rays) tran.transform(rays, 0, 0, 0, 0, 0, pi / 2, coords=gratc2) #Go to hub and diffract #Add yaw yaw = grat.blazeYaw(1.5 * pi / 180, 2.4, 3, 160.) tran.transform(rays, 0, 0, 0, 0, 0, yaw, coords=gratc2) tran.transform(rays, 0, -hubdist + disp, 0, 0, 0, 0, coords=gratc2) tran.reflect(rays) tran.radgrat(rays, 160. / hubdist, order, wave) pdb.set_trace() #Go back to reference frame of grating rays = tran.applyT(rays, gratc2, inverse=True) #Back to global #rays = tran.applyT(rays,gratc) #forward to grating #Go to focus focusc = [tran.tr.identity_matrix()] * 4 surf.focusY(rays, coords=focusc) #Get rid of mean X and Y tran.transform(rays,np.mean(rays[1]),np.mean(rays[2]),0,0,0,0,\ coords=focusc) return rays,[gratc[1][i][-1] for i in range(3)],\ [focusc[1][i][-1] for i in range(3)]
def testRadApprox(num,order=1,wave=1.,radapprox=False,N=3,f=None,yaw=0.,\ azwidth=66.*.68,autofocus=False,returnMet=False,axwidth=2.5): """ """ #Set up converging source rays = source.convergingbeam2(12e3,-azwidth/2,azwidth/2,\ -axwidth/2,axwidth/2,num,0.) tran.transform(rays,0,0,12e3,0,0,0) tran.transform(rays,0,0,0,88.5*np.pi/180.,0,0) tran.transform(rays,0,0,0,0,0,yaw) surf.flat(rays) #Place grating if radapprox is False: tran.reflect(rays) tran.transform(rays,0,-12e3,0,0,0,0) tran.radgrat(rays,160./12e3,order,wave) tran.transform(rays,0,12e3,0,0,0,0) tran.transform(rays,0,0,0,0,0,-yaw) else: tran.reflect(rays) gratedges = np.linspace(-50.,50.,N+1) for i in range(N): ind = np.logical_and(rays[2]>gratedges[i],\ rays[2]<gratedges[i+1]) d = (12e3+np.mean(gratedges[i:i+2]))/12e3*160. if np.sum(ind)>0: tran.grat(rays,d,-order,wave,ind=ind) tran.transform(rays,0,0,0,0,0,-yaw) #Go to focal plane tran.transform(rays,0,0,0,-88.5*np.pi/180.,0,0) tran.transform(rays,0,0,0,0,0,np.pi/2) if f is not None: try: tran.transform(rays,0,0,-f,0,0,0) surf.flat(rays) except: pdb.set_trace() if autofocus is True: surf.focusY(rays) if returnMet is True: return anal.hpdY(rays)/12e3*180/np.pi*60**2 return rays
def linearity(polyOrder=1,wavelength=np.linspace(0.,1.57*4.,100),\ opgalign=[0,0,0,0,0,0]): """ Trace a range of wavelengths, determine spot centroids, and then fit x centroid vs wavelength to a polynomial. Return polynomial coefficients and both RMS and PV deviation. """ #Get alignment parameters yaw = grat.blazeYaw(1.5*np.pi/180,1.575757,3,160.) rays,rec = test(1000,yaw=yaw,order=6,wave=1.575757/2.,rrays=True) f = -surf.focusY(rays) #Perform linearity scan cen = [test(10000,yaw=yaw,order=1,rcen=True,opgalign=opgalign,wave=w,f=f) \ for w in wavelength] cen = np.transpose(np.array(cen)) #Perform polynomial fit fit = np.polyfit(wavelength,cen[1],polyOrder) recon = np.polyval(fit,wavelength) rms = np.sqrt(np.mean((recon-cen[1])**2)) pv = np.max(np.abs(recon-cen[1])) #Plot plt.plot(wavelength,cen[1]-recon,label=str(opgalign[-1]*180/np.pi)) return cen,(rms,pv)
def alignmentSensitivities(): """ Trace Al K Littrow configuration. For each DoF, apply +- offsets and measure centroids. Fit resulting centroids vs. offset and determine slope and non-linearity """ #Get alignment parameters yaw = grat.blazeYaw(1.5*np.pi/180,1.575757,3,160.) rays,rec = test(1000,yaw=yaw,order=6,wave=1.575757/2.,rrays=True) f = -surf.focusY(rays) #Perform raytrace scans tr = np.linspace(-5.,5.,100) rot = np.linspace(-.6e-3,.6e-3,100) tx = np.array([[test(1000,yaw=yaw,wave=1240./1490,order=6,\ opgalign=misalign(dof,off),\ f=f,rcen=True) for off in tr] \ for dof in range(3)]) rx = np.array([[test(1000,yaw=yaw,wave=1240./1490,order=6,\ opgalign=misalign(dof,off),\ f=f,rcen=True) for off in rot] \ for dof in range(3,6)]) #Fit results to 2nd or 3rd order polynomial #Get derivative at off=0. #Compute peak-to-valley departure from this line #Compute peak-to-valley departure from best fit line #np.polyfit(tr,t[:,0] tx = tx.transpose(0,2,1) rx = rx.transpose(0,2,1) tfit = [[np.polyfit(tr,m,3) for m in t] for t in tx] rfit = [[np.polyfit(rot,m,3) for m in t] for t in rx] tslope = [[m[-2]/12e3*180/pi*60**2 for m in t] for t in tfit] #arcsec/mm rslope = [[m[-2]/12e3 for m in t] for t in rfit] #rad/rad=arcsec/arcsec tdiff = [[(m[1]*tr[-1]**2+m[0]*tr[-1]**3)/\ (m[2]*tr[-1]) for m in t] for t in tfit] rdiff = [[(m[1]*rot[-1]**2+m[0]*rot[-1]**3)/\ (m[2]*rot[-1]) for m in t] for t in rfit] pdb.set_trace() return [tslope,rslope,tdiff,rdiff]
def traceToTestOptic1m(N, app=75., coloffset=0., cghalign=np.zeros(6)): """Trace a set of rays from the point source to the nominal test optic location Return the rays at the plane tangent to the nominal source position. """ #Set up source div = app / 1935.033 rays = sources.pointsource(div, N) #Trace through collimator tran.transform(rays, 0, 0, 1935.033 + coloffset, 0, 0, 0) surf.flat(rays, nr=1.) lenses.collimator6(rays) ## tran.transform(rays,0,0,-coloffset,0,0,0) #Trace to CGH tran.transform(rays, 0, 0, 100., 0, 0, 0) #Apply proper CGH misalignment tran.transform(rays, 0, 0, 0, -10. * pi / 180, 0, 0) #Apply CGH misalignment tran.transform(rays, *cghalign) #Trace through CGH surf.flat(rays, nr=1.) tran.refract(rays, 1., nsil) tran.transform(rays, 0, 0, 6.35, 0, 0, 0) surf.flat(rays, nr=nsil) tran.refract(rays, nsil, 1.) surf.zernphase(rays, -cgh1m, 80., 632.82e-6) #Reverse CGH misalignment tran.itransform(rays, *cghalign) #Go to line focus line = surf.focusY(rays, nr=1.) #Go to test optic tran.transform(rays, 0, 0, 1000., 0, 0, 0) surf.flat(rays, nr=1.) #Go to 1m cylindrical radius of curvature px, py = anal.measurePower(rays, 200, 200) tran.transform(rays, 0, 0, 1000 + py, 0, 0, 0) surf.flat(rays, nr=1.) return rays, line
def reproduceChevron(num,rin=220.,axlength=100.,azwidth=50.,F=8.4e3,\ hubdist=8e3,radapprox=False,order=1,wave=.83,f=None,\ autofocus=False,returnMet=False,yaw=0.,N=1,\ gratalign=np.zeros(6)): #Create Wolter beam rout = conic.primrad(F+axlength,rin,F) rays = source.subannulus(rin,rout,azwidth/rin,num,zhat=-1.) surf.wolterprimary(rays,rin,F) tran.reflect(rays) surf.woltersecondary(rays,rin,F) tran.reflect(rays) tran.transform(rays,0,0,0,0,0,np.pi/2) #Go to focus surf.focusI(rays) #Steer beam coords = [tran.tr.identity_matrix()]*4 tran.transform(rays,0,0,0,np.mean(rays[5]),-np.mean(rays[4]),0) pdb.set_trace() #Go up to grating tran.transform(rays,0,0,hubdist/np.cos(1.5*np.pi/180),0,0,0) #Go to incidence angle tran.transform(rays,0,0,0,91.5*np.pi/180,0,0) tran.transform(rays,0,0,0,0,0,yaw) #Apply grating misalignment tran.transform(rays,*gratalign) surf.flat(rays) #Get rid of rays outside grating ind = np.logical_and(np.abs(rays[2])<16,np.abs(rays[1])<25/2.) rays = tran.vignette(rays,ind=ind) plt.figure('grat') plt.clf() plt.plot(rays[1],rays[2],'.') plt.title('Beam Footprint') #Place grating if radapprox is False: tran.reflect(rays) tran.transform(rays,0,-hubdist,0,0,0,0) tran.radgrat(rays,160./hubdist,order,wave) tran.transform(rays,0,hubdist,0,0,0,0) else: tran.reflect(rays) gratedges = np.linspace(-16.,16.,N+1) for i in range(N): ind = np.logical_and(rays[2]>gratedges[i],\ rays[2]<gratedges[i+1]) d = (hubdist+np.mean(gratedges[i:i+2]))/hubdist*160. if np.sum(ind)>0: tran.grat(rays,d,-order,wave,ind=ind) #Go to focal plane tran.transform(rays,*gratalign) tran.transform(rays,0,0,0,0,0,-yaw) tran.transform(rays,0,0,0,-91.5*np.pi/180.,0,0) tran.transform(rays,0,0,0,0,0,np.pi/2) if f is not None: try: tran.transform(rays,0,0,-f,0,0,0) surf.flat(rays) except: pdb.set_trace() if autofocus is True: surf.focusY(rays) if returnMet is True: return anal.hpdY(rays)/F*180/np.pi*60**2 plt.figure('LSF') plt.clf() plt.plot(rays[1],rays[2],'.') plt.title('LSF') return rays
def gratArray(rays,outerrad,hubdist,angle,inc,l=95.,bestFocus=None,\ weights=None,order=0,blazeYaw=0.,wave=1.,offX=0.,\ coords=None,vis=False): """Trace rays leaving SPO petal to the fanned grating array. Start with outermost radius and rotate grating array about the hub. Define outermost grating position by max ray radius at desired axial height. Rays have been traced to bottom of outermost grating. """ #Visualization bookkeeping xg, yg, zg = [np.zeros(len(rays[1]))] * 3 x, y = rays[1:3] #Dummy rays to ensure return of reference frame ## rays2 = sources.subannulus(220.,223.,10.*pi/180,100) #Put origin at bottom of outermost grating tran.transform(rays, outerrad, 0, 0, 0, 0, 0, coords=coords) ## PT.transform(rays2,outerrad,0,0,0,0,0) #Go to proper incidence angle of grating tran.transform(rays, 0, 0, 0, 0, 0, -pi / 2, coords=coords) tran.transform(rays, 0, 0, 0, -pi / 2 - angle + inc, 0, 0, coords=coords) ## PT.transform(rays2,0,0,0,0,0,-pi/2) ## PT.transform(rays2,0,0,0,-pi/2-angle+inc,0,0) #Go to hub tran.transform(rays, 0, 0, 0, 0, 0, blazeYaw, coords=coords) #Put in blaze tran.transform(rays, 0, hubdist, 0, 0, 0, 0, coords=coords) ## PT.transform(rays2,0,0,0,0,0,blazeYaw) #Put in blaze ## PT.transform(rays2,0,hubdist,0,0,0,0) #Trace out gratings until no rays hit a grating #Flat #Indices #Reflect #Apply Grating #Next #Edit to only flat rays with a substantial incidence angle indg = np.abs(np.arcsin(rays[6])) > .001 surf.flat(rays, ind=indg) rho = -sqrt(x**2 + y**2) * np.sign(y) ind = np.logical_and(rho > hubdist, rho < l + hubdist) ## pdb.set_trace() ind2 = np.copy(ind) #offx subtracted to prevent numerical vignetting...this #is accounted for with numerical factors, so don't want #any rays to be missed ang = l * sin(inc - offX) / hubdist * .95 i = 0 prev = np.copy(ind) #Loop condition needs to be rays not diffracted > 0 while np.sum(prev) < len(rays[1]): i = i + 1 if np.sum(ind2) > 0: tran.reflect(rays, ind=ind2) tran.radgrat(rays, 160. / hubdist, order, wave, ind=ind2) tran.transform(rays, 0, 0, 0, ang, 0, 0, coords=coords) ## PT.transform(rays2,0,0,0,ang,0,0) indg = np.abs(np.arcsin(rays[6])) > .001 indg = np.logical_and(np.invert(prev), indg) surf.flat(rays, ind=indg) ## pdb.set_trace() #Determine rays hitting new grating rho = -sqrt(x**2 + y**2) * np.sign(y) ind = np.logical_and(rho > hubdist, rho < l + hubdist) ind2 = np.logical_and(np.invert(prev), ind) #Remove previous rays prev = np.logical_or(prev, ind) #Add rays hitting new grating #sys.stdout.write('%i \r' % i) #sys.stdout.flush() tran.reflect(rays, ind=ind2) tran.radgrat(rays, 160. / hubdist, order, wave, ind=ind2) ## #Go to focal plane ## PT.transform(rays,0,-hubdist,0,0,0,0) ## PT.transform(rays,0,0,0,0,0,-blazeYaw) #Reverse blaze ## #Currently at bottom point of innermost grating ## pdb.set_trace() if vis is True: #Get hub position hub = tran.applyTPos(0, 0, 0, coords, inverse=True) pyfits.writeto('HubPos.fits', np.array(hub), clobber=True) #Get back to original outermost grating reference frame tran.transform(rays, 0, 0, 0, -ang * i, 0, 0, coords=coords) tran.transform(rays, 0, -hubdist, 0, 0, 0, 0, coords=coords) tran.transform(rays, 0, 0, 0, 0, 0, -blazeYaw, coords=coords) tran.transform(rays, 0, 0, 0, pi / 2 + angle - inc, 0, 0, coords=coords) tran.transform(rays, 0, 0, 0, 0, 0, pi / 2, coords=coords) tran.transform(rays, -outerrad, 0, 0, 0, 0, 0, coords=coords) ## PT.transform(rays2,0,0,0,-ang*i,0,0) ## PT.transform(rays2,0,-hubdist,0,0,0,0) ## PT.transform(rays2,0,0,0,0,0,-blazeYaw) ## PT.transform(rays2,0,0,0,pi/2+angle-inc,0,0) ## PT.transform(rays2,0,0,0,0,0,pi/2) ## PT.transform(rays2,-outerrad,0,0,0,0,0) #Export grating ray positions if vis is True: rays2 = tran.applyT(rays, coords, inverse=True) pyfits.writeto('GratingPos.fits',\ np.array([rays2[1],rays2[2],rays2[3]]),\ clobber=True) pdb.set_trace() #Should be there surf.flat(rays) ## PT.transform(rays,0,hubdist,0,0,0,0) ## PT.transform(rays,0,0,0,-ang*i+pi/2+angle-inc,0,0) ## PT.transform(rays,0,0,0,0,0,pi/2) ## PT.flat(rays) #Find focus if bestFocus is None: return surf.focusY(rays, weights=weights) ## ## #Focus already found, tracing diffracted line ## PT.transform(rays,0,0,bestFocus,0,0,0) ## PT.flat(rays) return None