def setupSource(wave,N,radius=450.,focal=8000.,scatter=50e-6,\ gwidth=25.,glength=32.,pitch=0.,yaw=0.,roll=0.): """Set up converging beam with some scatter. Idea is to place a grating at radius and focal length with an incidence angle of 1.5 degrees """ #Setup rays over grating surface PT.x = np.random.uniform(low=-gwidth / 2, high=gwidth / 2, size=N) PT.y = np.random.uniform(low=-glength / 2, high=glength / 2, size=N) PT.z = np.repeat(0., N) PT.l = np.zeros(N) PT.m = np.zeros(N) PT.n = np.zeros(N) PT.ux = np.zeros(N) PT.uy = np.zeros(N) PT.uz = np.repeat(1., N) #Transform to nominal focus to set ray cosines PT.transform(0, 0, 0, -88.5 * np.pi / 180, 0, 0) PT.transform(0, radius, -focal, 0, 0, 0) rad = np.sqrt(PT.x**2 + PT.y**2 + PT.z**2) PT.l = -PT.x / rad PT.m = -PT.y / rad PT.n = -PT.z / rad #Add scatter PT.l = PT.l + scatter / 10. * np.random.normal(size=N) PT.m = PT.m + scatter * np.random.normal(size=N) PT.n = -np.sqrt(1. - PT.l**2 - PT.m**2) #Go back to plane of of grating PT.transform(0, -radius, focal, 0, 0, 0) PT.transform(0, 0, 0, 88.5 * np.pi / 180, 0, np.pi) #Place grating and diffract hubdist = np.sqrt(radius**2 + focal**2) * np.cos(1.5 * np.pi / 180) PT.flat() PT.reflect() PT.transform(0, 0, 0, pitch, roll, yaw) PT.radgrat(hubdist, 160. / hubdist, 1, wave) PT.itransform(0, 0, 0, pitch, roll, yaw) #Go to focal plane PT.transform(0, 0, 0, np.pi / 2, 0, 0) PT.transform(0, 0, -hubdist, 0, 0, 0) PT.transform(0, 0, 27.27727728 - .04904905, 0, 0, 0) PT.flat() #plt.plot(PT.x,PT.y,'.') return PT.centroid()
def SXperformance(theta,energy,rough,bestsurface=False,optsurface=False): """Go through a SMART-X prescription file and compute area weighted performance for a flat focal plane """ #Load in rx data ## rx = np.transpose(np.genfromtxt('/home/rallured/Dropbox/AXRO/WSTracing/' ## 'mirror-design-260sh-200mmlong-040mmthick' ## '-3mdiam-10mfl-10arcmin-fov-planarIntersept032713.csv',\ ## delimiter=',')) rx = np.transpose(np.genfromtxt('/home/rallured/Dropbox/AXRO/WSTracing/' '150528_Pauls_Rx.csv',delimiter=',')) geo = np.transpose(np.genfromtxt('/home/rallured/Dropbox/AXRO/WSTracing/' 'geometric_transmission_102711.txt')) therm = np.transpose(np.genfromtxt('/home/rallured/Dropbox/AXRO/' 'WSTracing/thermal_shield_transmission_102711.txt')) f = np.sqrt(rx[1][-1]**2+10000.**2) z = np.sqrt(f**2-rx[1]**2) #spherical ## z = np.repeat(10000.,np.size(rx[1])) ## ind = rx[0] > 210. ## rx = rx[:,ind] Ns = np.shape(rx)[1] #Loop through and compute a resolution and a weight for each shell hpdTelescope = np.zeros(np.size(theta)) rmsTelescope = np.zeros(np.size(theta)) delta = np.zeros(np.size(theta)) cent = np.zeros(np.size(theta)) platefrac = np.zeros(np.size(theta)) #fig = plt.figure() for t in theta[:]: xi = np.array([]) yi = np.array([]) l = np.array([]) m = np.array([]) n = np.array([]) weights = np.array([]) #plt.clf() tstart = time.time() plate = np.zeros(Ns) for s in np.arange(0,Ns): if geo[1][s] > 0.: sys.stdout.write('Shell: %03i \r' % s) sys.stdout.flush() r,rays = traceWSShell(1000,t,rx[1][s],z[s],z[s]+225.,z[s]+25.,\ z[s]-25.,z[s]-225.,energy,rough) r = r*geo[1][s]*rx[9][s] #Reflectivity*area*alignmentbars*vign #Account for thermal shield in shells 220-321 if s > 219: r = r * therm[1][np.abs(energy/1000.-therm[0]).argmin()] r = np.repeat(r,np.size(rays[1])) weights = np.append(weights,r) PT.conic(1107.799202,-1.) xi = np.append(xi,rays[1]) yi = np.append(yi,rays[2]) l = np.append(l,rays[4]) m = np.append(m,rays[5]) n = np.append(n,rays[6]) if s%10==0: plt.plot(rays[1][:100],rays[2][:100],'.') plate[s] = anal.centroid(rays,weights=r)[0] print time.time()-tstart #Have list of photon positions and weights #Need to compute centroid and then FoM #Normalize weights weights = weights/np.sum(weights) xi = np.array(xi,order='F') yi = np.array(yi,order='F') zi = np.zeros(np.size(xi)).astype('float') li = np.array(l,order='F') mi = np.array(m,order='F') ni = np.array(n,order='F') uxi = np.zeros(np.size(xi)).astype('float') uyi = np.zeros(np.size(xi)).astype('float') uzi = np.zeros(np.size(xi)).astype('float') rays = [np.zeros(np.size(xi)).astype('float'),\ xi,yi,zi,\ li,mi,ni,\ uxi,uyi,uzi] if bestsurface: rays = tran.transform(rays,0,0,.25,0,0,0) surf.focusI(rays,weights=weights) if optsurface: PT.conic(1107.799202,-1.) #Emprically found best surface 1128.058314 #Compute FoM rmsTelescope[t==theta] = PT.rmsCentroid(weights=weights)/10000. hpdTelescope[t==theta] = PT.hpd(weights=weights)/10000. cx,cy = PT.centroid() cent[t==theta] = cx ind = geo[1] > 0. platefrac[t==theta] = np.std(plate[ind]/1e4)/rmsTelescope[t==theta] print hpdTelescope[t==theta],rmsTelescope[t==theta] return hpdTelescope,rmsTelescope,delta,cent,plate
def traceChaseParam(num, psi, theta, alpha, L1, z0, bestFocus=False, chaseFocus=False): """Trace a WS mirror pair using the parameters in Eq. 13 of Chase & VanSpeybroeck Return the RMS radius of the focus Can specify whether to find the best focus or not """ #Define annulus of source rays r0 = np.tan(4 * alpha) * z0 alphap = 2 * alpha / (1 + 1 / psi) r1 = PT.wsPrimRad(z0 + L1, 1., r0, z0) #np.tan(alphap/2.)*L1 + r0 PT.annulus(r0, r1, num) PT.transform(0, 0, 0, np.pi, 0, 0) PT.transform(0, 0, -10000., 0, 0, 0) pdb.set_trace() #Trace to primary PT.wsPrimary(r0, z0, psi) #Handle vignetting PT.vignette() ind = np.logical_and(PT.z < z0 + L1, PT.z > z0) PT.vignette(ind=ind) ## pdb.set_trace() #Apply pointing error PT.l = PT.l + np.sin(theta) PT.n = -np.sqrt(1 - PT.l**2) #Anything hitting backside goes away dot = PT.l * PT.ux + PT.m * PT.uy + PT.n * PT.uz ind = dot < 0. PT.vignette(ind=ind) if np.size(PT.x) < 1: return 0., 0., 0. #Reflect PT.reflect() N1 = np.size(PT.x) #Trace to secondary PT.wsSecondary(r0, z0, psi) #Vignette anything that did not converge PT.vignette() #Vignette anything hitting the backside dot = PT.l * PT.ux + PT.m * PT.uy + PT.n * PT.uz ind = dot < 0. PT.vignette(ind=ind) ## #Vignette anything outside the physical range of the mirror ## ind = np.logical_and(PT.z>z0-L1,PT.z<z0) ## PT.vignette(ind=ind) if np.size(PT.x) < 1: return 0., 0., 0. PT.reflect() #Trace to focal plane PT.flat() cx, cy = PT.centroid() r = np.sqrt(cx**2 + cy**2) #Find best focus delta = 0. if chaseFocus or bestFocus: delta = .0625 * (psi + 1) * (r**2 * L1 / z0**2) * (1 / np.tan(alpha))**2 PT.transform(0, 0, delta, 0, 0, 0) PT.flat() delta2 = 0. delta3 = 0. if bestFocus: try: delta2 = PT.findimageplane(20., 100) PT.transform(0, 0, delta2, 0, 0, 0) delta3 = PT.findimageplane(1., 100) PT.transform(0, 0, delta3, 0, 0, 0) except: pdb.set_trace() PT.flat() return PT.rmsCentroid() / z0, delta + delta2 + delta3, r
def traceWSShell(num,theta,r0,z0,phigh,plow,shigh,slow,\ chaseFocus=False,bestFocus=False): """Trace a WS mirror pair with 10 m focal length and mirror axial cutoffs defined by phigh,plow """ #Define annulus of source rays a, p, d, e = con.woltparam(r0, z0) r1 = PT.wsPrimRad(plow, 1., r0, z0) #np.tan(a/2.)*(plow-10000.) + r0 r2 = PT.wsPrimRad(phigh, 1., r0, z0) #np.tan(a/2.)*(phigh-10000.) + r0 ## r2 = np.mean([r1,r2]) PT.annulus(r1, r2, num) PT.transform(0, 0, 0, np.pi, 0, 0) PT.transform(0, 0, z0, 0, 0, 0) ## pdb.set_trace() #Trace to primary PT.wsPrimary(r0, z0, 1.) #Handle vignetting PT.vignette() ind = np.logical_and(PT.z < phigh, PT.z > plow) PT.vignette(ind=ind) #Vignette rays hitting backside of mirror dot = PT.l * PT.ux + PT.m * PT.uy + PT.n * PT.uz ind = dot < 0. PT.vignette(ind=ind) #If all rays are vignetted, return if np.size(PT.x) < 1: return 0., 0., 0. #Apply pointing error PT.l = PT.l + np.sin(theta) PT.n = -np.sqrt(1 - PT.l**2) #Reflect PT.reflect() #Compute mean incidence angle for reflectivity ## ang = np.abs(np.mean(np.arcsin(dot))) #radians ## refl1 = CXCreflIr(ang,energy,rough) #Total rays entering primary aperture N1 = np.size(PT.x) #Trace to secondary PT.wsSecondary(r0, z0, 1.) #Vignette anything that did not converge PT.vignette() #Vignette anything outside the physical range of the mirror ind = np.logical_and(PT.z > slow, PT.z < shigh) PT.vignette(ind=ind) #Vignette anything hitting the backside dot = PT.l * PT.ux + PT.m * PT.uy + PT.n * PT.uz ind = dot < 0. PT.vignette(ind=ind) if np.size(PT.x) < 1: return 0., 0., 0. PT.reflect() #Compute mean incidence angle for reflectivity ## ang = np.abs(np.mean(np.arcsin(dot))) #radians ## refl2 = CXCreflIr(ang,energy,rough) #Trace to focal plane PT.flat() #Find Chase focus delta = 0. if chaseFocus or bestFocus: cx, cy = PT.centroid() r = np.sqrt(cx**2 + cy**2) delta = .0625*(1.+1)*(r**2*(phigh-plow)/10000.**2)\ *(1/np.tan(a))**2 PT.transform(0, 0, delta, 0, 0, 0) PT.flat() #Find best focus delta2 = 0. delta3 = 0. if bestFocus: try: delta2 = PT.findimageplane(20., 100) PT.transform(0, 0, delta2, 0, 0, 0) delta3 = PT.findimageplane(1., 100) PT.transform(0, 0, delta3, 0, 0, 0) except: pdb.set_trace() PT.flat() #return refl1*refl2 return PT.hpd(), PT.rmsCentroid(), delta