# Define inner & outer radii to create rays. rp_front = conic.primrad(z0 + mirror_sep / 2 + mirror_len, r0, z0) rp_back = conic.primrad(z0 + mirror_sep / 2, r0, z0) # Define initial rays in subannulus. rays = sources.subannulus(rp_back, rp_front, np.radians(30.), 100000) # Transform rays to intersection plane of optic. trans.transform(rays, 0, 0, -z0, 0, 0, 0) # Rotate 90 degrees so that diffraction occurs in x-axis. trans.transform(rays, 0, 0, 0, 0, 0, -np.radians(90.)) # Pass through primary. surfaces.wolterprimary(rays, r0, z0) trans.reflect(rays) # # Add some scatter. ogre.beckmann_scatter(rays, 0, 0, 1.48e-5) # Pass through secondary. surfaces.woltersecondary(rays, r0, z0) trans.reflect(rays) # Go to optic focus. surfaces.focusX(rays) # Define grating parameters. d = 160. # Groove period @ 3300 mm [nm] L = 3250. # Center of grating [mm]
zp_back = z0 + mirror_sep / 2 # Axial position of parabola front. zp_front = zp_back + mirror_length # axial position of parabola back. rp_front = [conic.primrad(zp_front, r, z0) for r in r_int] rp_back = [conic.primrad(zp_back, r, z0) for r in r_int] # Loop through each mirror in mirror stack. for i in range(len(r_int)): # Find photons which will hit this mirror shell. r = np.sqrt(rays[1]**2 + rays[2]**2) ind = np.where((r > rp_back[i]) & (r < rp_front[i]))[0] # Create new ray object with only these rays. ind_rays = [r[ind] for r in rays] # Propagate these photons to primary mirror. surfaces.wolterprimary(ind_rays, r_int[i], z0) # Find which photons interact with this mirror. ind = np.where((ind_rays[3] > (z0 + mirror_sep / 2)) & (ind_rays[3] < (z0 + mirror_sep / 2 + mirror_length)))[0] # Keep only the photons which interact with the actual size # of the mirror ind_rays = [r[ind] for r in ind_rays] # Reflect photons off of primary. trans.reflect(ind_rays) # # Add Beckmann + Gaussian scatter. # # ogre.beckmann_scatter(ind_rays, 0, 0, 2e-5) # ind_rays[4] = ind_rays[4] + np.random.normal(scale=1e-7, size=len(ind_rays[4]))