def gratArray(outerrad, hubdist, angle, inc, l=95.): """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. """ #Put origin at bottom of outermost grating PT.transform(outerrad, 0, 0, 0, 0, 0) #Go to proper incidence angle of grating PT.transform(0, 0, 0, 0, 0, -pi / 2) PT.transform(0, 0, 0, -pi / 2 - angle + inc, 0, 0) #Go to hub PT.transform(0, hubdist, 0, 0, 0, 0) #Trace out gratings until no rays hit a grating #Flat #Indices #Reflect #Apply Grating #Next PT.flat() ind = np.logical_and(PT.y < -hubdist, PT.y > -l - hubdist) ang = l * sin(inc) / hubdist i = 0 while np.sum(ind) > 0: i = i + 1 PT.reflect(ind=ind) PT.radgrat(0., 160. / hubdist, 0, 1., ind=ind) PT.transform(0, 0, 0, ang, 0, 0) PT.flat() ind = np.logical_and(PT.y < -hubdist, PT.y > -l - hubdist) sys.stdout.write('%i \r' % i) sys.stdout.flush() pdb.set_trace()
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 arc(inc, yaw, hubdist, wave, order, dpermm): """Return x and y positions of diffraction arc as a function of wavelength for a given order""" #Set up source ray PT.circularbeam(0., 1) #Transform to grating frame PT.transform(0, 0, 0, pi / 2 + inc, 0, 0) PT.transform(0, 0, 0, 0, 0, yaw) PT.flat() #Apply grating PT.reflect() PT.radgrat(hubdist, dpermm, order, wave) #Go to focus PT.transform(0, 0, 0, 0, 0, -yaw) PT.transform(0, hubdist, 0, 0, 0, 0) PT.transform(0, 0, 0, pi / 2, 0, 0) PT.flat() #Get ray positions return PT.x[0], PT.y[0]
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])