def do_xou_focus(input_rays, xou): prays = input_rays.yield_prays() rays = ArcUtil.undo_ray_transform_to_coordinate_system( prays, xou.xou_coords) ray_object = ArcRays.ArcusRays(rays, input_rays.wave) focused_spo_rays, dz = bring_rays_to_disp_focus(ray_object) focus_pos = array([mean(focused_spo_rays.x), mean(focused_spo_rays.y), dz]) prays = focused_spo_rays.yield_prays() hpd = anal.hpd(prays) / arcsec fwhmX = anal.rmsX(prays) * 2.35 / arcsec return focused_spo_rays, focus_pos, hpd, fwhmX
def check_xou_quality(xous=gwat_xous): ############ gwat_rays = gwatf.make_gwat_source(N, wave, source_dist, clock_angles) spomm_rays = ArcSPO.SPOPetalTrace(gwat_rays, xous) m25_rays = spomm_rays.yield_object_indices( spomm_rays.xou_hit == xous['MM-0025'].xou_num) m27_rays = spomm_rays.yield_object_indices( spomm_rays.xou_hit == xous['MM-0027'].xou_num) focused_spo_rays, focus_pos, hpd27, fwhmX27 = gwatf.do_xou_focus( m27_rays, xous['MM-0027']) focused_spo_rays, focus_pos, hpd25, fwhmX25 = gwatf.do_xou_focus( m25_rays, xous['MM-0025']) focused_spo_rays, dz = gwatf.bring_rays_to_disp_focus(spomm_rays) hpd, fwhmX = anal.hpd(focused_spo_rays.yield_prays()) / arcsec, anal.rmsX( focused_spo_rays.yield_prays()) * 2.35 / arcsec print hpd27, hpd25, fwhmX27, fwhmX25, hpd, fwhmX return focused_spo_rays, hpd, fwhmX
def traceZeta(pmin,R0=220.,Z0=1e4,psi=1.,offaxis=0.,L=200.,az=100.,pause=False): """ Set initial aperture based on height of bottom of mirror above node (pmin). Assume 100 mm long mirrors. Then, trace to secondary and mark smin and smax for where the rays strike. Then trace out off axis field positions and determine RMS and HPD vs angle. """ #Set up aperture a0 = wsPrimrad(pmin,R0,Z0,psi) a1 = wsPrimrad(pmin+L,R0,Z0,psi) rays = sources.subannulus(a0,a1,az/R0,1e4) tran.transform(rays,0,0,-Z0,0,0,0) #Trace to primary and add off-axis angle surf.wsPrimary(rays,R0,Z0,psi) rays[4] = rays[4]+np.sin(offaxis) rays[6] = -np.sqrt(1.-rays[4]**2) tran.reflect(rays) #Trace to secondary surf.wsSecondary(rays,R0,Z0,psi) tran.reflect(rays) smax = np.nanmax(rays[3]) smin = np.nanmin(rays[3]) if pause is True: pdb.set_trace() #Go to focus f = surf.focusI(rays) #Compute merit functions hpd = anal.hpd(rays) rms = anal.rmsCentroid(rays) return smin,smax,f,hpd,rms
def calc_line_stats(prays, arcsec=arcsec): hpd = anal.hpd(prays) / arcsec fwhmX = anal.rmsX(prays) * 2.35 / arcsec return hpd, fwhmX
def traceXRS(rsec,smax,pmin,fun,nodegap,L=200.,Nshell=1e3,energy=1000.,\ rough=1.,offaxis=0.,rrays=False): """ Using output from defineRx, trace the nodes in a Lynx design. Provide number of sections, and the zeta as a function of radius interpolation function. Calculate node radii iteratively, providing appropriate gaps between nodes in order to limit off-axis vignetting. """ gap = L*3e-3+0.4 #.4 mm glass thickness plus vignetting #Trace through all shells, computing reflectivity and geometric area #for each shell previousrho = [] for i in range(len(smax)): #Variable to store radial position of bottom of previous #secondary mirror previousrho.append(0.) for r in rsec[i]: #Determine zeta for this shell...must be at least .01 psi = np.polyval(fun[i],r) psi = np.max([.01,psi]) #Set up aperture z = np.sqrt(1e4**2-r**2) a0 = wsPrimrad(pmin[i],r,z,psi=psi) a1 = wsPrimrad(pmin[i]+L,r,z,psi=psi) rays = sources.annulus(a0,a1,Nshell) tran.transform(rays,0,0,-z,0,0,0) #Set up weights (cm^2) weights = np.repeat((a1**2-a0**2) * np.pi / 100. / Nshell,Nshell) #Trace to primary surf.wsPrimary(rays,r,z,psi) rays[4] = rays[4]+np.sin(offaxis) rays[6] = -np.sqrt(1.-rays[4]**2) tran.reflect(rays) ang = anal.grazeAngle(rays) weights = weights*\ pol.computeReflectivities(ang,energy,rough,1,cons)[0] #Trace to secondary surf.wsSecondary(rays,r,z,psi) tran.reflect(rays) ang = anal.grazeAngle(rays) weights = weights*\ pol.computeReflectivities(ang,energy,rough,1,cons)[0] #Handle vignetting ind = np.logical_and(rays[3]>smax[i]-L,rays[3]<smax[i]) if sum(ind) == 0: pdb.set_trace() rays = tran.vignette(rays,ind=ind) weights = weights[ind] #Go to exit aperture and confirm rays don't #hit back of previous shell tran.transform(rays,0,0,smax[i]-L,0,0,0) surf.flat(rays) rho = np.sqrt(rays[1]**2+rays[2]**2) ind = rho > previousrho[-1] #if np.sum(ind)==0: #pdb.set_trace() if np.sum(~ind) > 100: print '%i rays hit back of shell' % np.sum(~ind) print r,psi #pdb.set_trace() rays = tran.vignette(rays,ind=ind) weights = weights[ind] previousrho.append(wsSecrad(smax[i]-L,r,z,psi=psi)+.4) #Go to focus if rrays is False: tran.transform(rays,0,0,-smax[i]+L,0,0,0) surf.flat(rays) #Accumulate master rays try: mrays = [np.concatenate([mrays[ti],rays[ti]]) for ti in range(10)] mweights = np.concatenate([mweights,weights]) except: mrays = rays mweights = weights if rrays is True: return mrays,mweights,previousrho #Go to focus try: surf.focusI(rays,weights=weights) except: pdb.set_trace() return anal.hpd(mrays,weights=mweights)/1e4*180/np.pi*60**2,\ anal.rmsCentroid(mrays,weights=mweights)/1e4*180/np.pi*60**2,\ np.sum(mweights)
def tracePerfectXRS(L=200.,nodegap=50.,Nshell=1e3,energy=1000.,\ rough=1.,offaxis=0.,rrays=False,rnodes=False): """ Trace rays through a perfect Lynx design where all the shells are on the spherical principle surface, with zeta equal to unity. """ #Construct node positions rad = np.array([200.]) z = np.sqrt(1e4**2-rad[-1]**2) #Gap is projected radial shell plus thickness plus vignetting gap rout = wsPrimrad(z+L+nodegap/2.,rad[-1],z) gap = L*3e-3 + 0.4 #Establish radius vector rad = np.array([]) for sec in range(3): rout = 0. #First node position rad = np.append(rad,200.+(1300./3)*sec) #rguess = np.linspace( while rout+gap < 200.+(1300./3)*(sec+1)-10.: #Need to adjust this condition #Compute parameters for current node z = np.sqrt(1e4**2-rad[-1]**2) rout = wsPrimrad(z+L+nodegap/2.,rad[-1],z) rad = np.append(rad,rout+gap) rad = rad[:-1] if rnodes is True: return rad #Use radial nodes and trace Lynx, keeping track of effective area previousrho = 0. for r in rad: #Set up aperture z = np.sqrt(1e4**2-r**2) a0 = wsPrimrad(z+nodegap/2.,r,z) a1 = wsPrimrad(z+nodegap/2.+L,r,z) rays = sources.annulus(a0,a1,Nshell) tran.transform(rays,0,0,-z,0,0,0) #Set up weights (cm^2) weights = np.repeat((a1**2-a0**2) * np.pi / 100. / Nshell,Nshell) #Trace to primary surf.wsPrimary(rays,r,z,1.) rays[4] = rays[4]+np.sin(offaxis) rays[6] = -np.sqrt(1.-rays[4]**2) tran.reflect(rays) ang = anal.grazeAngle(rays) weights = weights*\ pol.computeReflectivities(ang,energy,rough,1,cons)[0] #Trace to secondary surf.wsSecondary(rays,r,z,1.) tran.reflect(rays) ang = anal.grazeAngle(rays) weights = weights*\ pol.computeReflectivities(ang,energy,rough,1,cons)[0] #Handle vignetting ind = np.logical_and(rays[3]>z-nodegap/2.-L,rays[3]<z-nodegap/2.) if sum(ind) == 0: pdb.set_trace() rays = tran.vignette(rays,ind=ind) weights = weights[ind] #Go to exit aperture and confirm rays don't - EDIT HERE! #hit back of previous shell tran.transform(rays,0,0,z-nodegap/2-L,0,0,0) surf.flat(rays) rho = np.sqrt(rays[1]**2+rays[2]**2) ind = rho > previousrho #if np.sum(ind)==0: #pdb.set_trace() if np.sum(~ind) > 100: print '%i rays hit back of shell' % np.sum(~ind) print r #pdb.set_trace() rays = tran.vignette(rays,ind=ind) weights = weights[ind] previousrho = wsSecrad(z-nodegap/2-L,r,z)+.4 #Go to focus try: surf.focusI(rays,weights=weights) except: pdb.set_trace() #Accumulate master rays try: mrays = [np.concatenate([mrays[ti],rays[ti]]) for ti in range(10)] mweights = np.concatenate([mweights,weights]) except: mrays = rays mweights = weights if rrays is True: return mrays,mweights return anal.hpd(mrays,weights=mweights)/1e4*180/np.pi*60**2,\ anal.rmsCentroid(mrays,weights=mweights)/1e4*180/np.pi*60**2,\ np.sum(mweights)