In [2]:
# imports
from __future__ import division
import os, sys, time, math
import numpy as np
import matplotlib.pyplot as plt
import pyzdde.zdde as pyz
import pyzdde.arraytrace as at
%matplotlib inline

In [3]:
plotDir = os.path.join('C:\Users\CAD User\Desktop\lsstzemax\data', 'lsst_nominal')
if not os.path.isdir(plotDir): os.mkdir(plotDir)

In [4]:
ln = pyz.createLink() # create a DDE link object for communication

In [5]:
zfile = os.path.join('C:\Users\CAD User\Desktop\lsstzemax\zemax', 'lsst_nominal.zmx')

In [6]:
ln.zLoadFile(zfile)


Out[6]:
0

In [7]:
# Surfaces in the sequential lens data editor
ln.ipzGetLDE()


SURFACE DATA SUMMARY:

Surf       	Type        	Radius        	Thickness           	Glass        	Diameter        	Conic        	Comment
 OBJ	 STANDARD	       Infinity	       Infinity	                     	             0	              0
   1	 STANDARD	       Infinity	           1200	                     	      8858.927	              0	 Center Cap
   2	 STANDARD	       Infinity	              0	                     	      8785.601	              0	 Center plate 1
   3	 STANDARD	       Infinity	              0	                     	      8785.601	              0	 Center plate 2
   4	 COORDBRK	              -	              0	                     	             -	              -
   5	 STANDARD	       Infinity	              0	                     	      8785.601	              0	 Center plate 3
   6	 COORDBRK	              -	              0	                     	             -	              -
   7	 COORDBRK	              -	              0	                     	             -	              -
   8	 STANDARD	       Infinity	           1200	                     	      8785.601	              0	 Center plate 4
   9	 COORDBRK	              -	              0	                     	             -	              -
  10	 COORDBRK	              -	          -1200	                     	             -	              -
  11	 STANDARD	       Infinity	              0	                     	          9600	              0	 Spider top 1
  12	 STANDARD	       Infinity	          -13.6	                     	          9600	              0	 Spider top 2
  13	 STANDARD	          -5640	              0	                     	         10400	              0	 Upper TEA Baffle
  14	 STANDARD	       Infinity	              0	                     	          9600	              0	 Spider bottom 1
  15	 STANDARD	       Infinity	         1261.8	                     	          9600	              0	 Spider bottom 2
  16	 COORDBRK	              -	              0	                     	             -	              -
  17	 STANDARD	       Infinity	         779.01	                     	      8709.329	              0	 M2 Vertex
  18	 STANDARD	       Infinity	       4937.791	                     	         10250	              0	 Lower TEA Baffle
  19	 STANDARD	       Infinity	          -2852	                     	      8360.001	              0	 Dummy to M1 CA
  20	 STANDARD	       Infinity	           2852	                     	          9600	              0	 M1/M3 Mirror Cover
  21	 STANDARD	       Infinity	          439.4	                     	      8360.001	              0	 M1 CA Baffle
 STO	 EVENASPH	         -19835	         -439.4	               MIRROR	          8360	         -1.215	 M1
  23	 STANDARD	       Infinity	      -4937.791	                     	      8359.992	              0	 M1 CA Baffle
  24	 STANDARD	       Infinity	        -779.01	                     	      4382.059	              0	 Middle TEA Baffle
  25	 EVENASPH	          -6788	         779.01	               MIRROR	          3420	         -0.222	 M2
  26	 STANDARD	       Infinity	       5377.191	                     	      3865.168	              0	 M2 Baffle Bottom
  27	 STANDARD	       Infinity	          233.8	                     	      5462.858	              0	 M1/M3 Offset
  28	 EVENASPH	        -8344.5	        -3630.5	               MIRROR	          5016	          0.155	 M3
  29	 STANDARD	       Infinity	     -0.7725882	                     	      1776.356	              0
  30	 STANDARD	          -2824	         -82.23	               SILICA	          1550	              0	 L1
  31	 STANDARD	          -5021	       -412.642	                     	          1550	              0
  32	 STANDARD	       Infinity	            -30	               SILICA	          1102	              0	 L2
  33	 EVENASPH	          -2529	        -349.58	                     	          1102	          -1.57
  34	 STANDARD	          -5632	          -17.9	               SILICA	           756	              0	 Filter
  35	 STANDARD	          -5606	          -51.1	                     	           756	              0
  36	 EVENASPH	          -3169	            -60	               SILICA	           722	         -0.962	 L3
  37	 STANDARD	          13360	          -28.5	                     	           722	              0
 IMA	 STANDARD	       Infinity	               	                     	           634	              0	 Detector

In [8]:
# General System properties
ln.zGetSystem()


Out[8]:
systemData(numSurf=38, unitCode=0, stopSurf=22, nonAxialFlag=1, rayAimingType=1, adjustIndex=1, temp=20.0, pressure=1, globalRefSurf=38)

In [9]:
# Paraxial/ first order properties of the system
ln.zGetFirst()


Out[9]:
firstOrderData(EFL=10310.06533, paraWorkFNum=1.233261403, realWorkFNum=1.23327911, paraImgHeight=315.0009857, paraMag=0.0)

In [10]:
# duplicate of zGetFirst() for use in the notebook
ln.ipzGetFirst()


Paraxial magnification : 0.0
Real working F/#       : 1.23327911
Effective focal length : 10310.06533
Paraxial working F/#   : 1.233261403
Paraxial image height  : 315.0009857

In [11]:
# ... another example is the zGetSystemAper() that returns information about the aperture. 
# The aperture type is retuned as a code which we might not remember always ...
ln.zGetSystemAper()


Out[11]:
systemAper(apertureType=0, stopSurf=22, value=8360.0)

In [12]:
# ...with the duplicate, ipzGetSystemAper(), we can immediately know that
# the aperture type is the Entrance Pupil Diameter (EPD)
ln.ipzGetSystemAper()


Aperture Type           : EPD
Value (system aperture) : 8360.0
Stop surface            : 22

In [13]:
# information about the field definition
ln.ipzGetFieldData()


Field Normalization : Radial
Type                : Angles in degrees
Number of Fields    : 7
Max Y               : 1.75
Max X               : 1.75
   X       Y     Weight   VDX     VDY     VCX     VCY     VAN   
 0.00    0.00   1.0000  0.0000  0.0000  0.0000  0.0000  0.0000  
 0.00    0.50   1.0000  0.0000  0.0000  0.0000  0.0000  0.0000  
 0.00    1.23   1.0000  0.0000  0.0000  0.0000  0.0000  0.0000  
 0.00    1.75   1.0000  0.0000  0.0000  0.0000  0.0000  0.0000  
 0.00   -0.50   1.0000  0.0000  0.0000  0.0000  0.0000  0.0000  
 0.00   -1.23   1.0000  0.0000  0.0000  0.0000  0.0000  0.0000  
 0.00   -1.75   1.0000  0.0000  0.0000  0.0000  0.0000  0.0000  

In [13]:
hx = 0.0
hy = 0.0
spirals = 10 #100
rays = 600   #6000
(xu,yu,zu,intensityu) = ln.zSpiralSpot(hx,hy,1,spirals,rays)
(xg,yg,zg,intensityg) = ln.zSpiralSpot(hx,hy,2,spirals,rays)
(xr,yr,zr,intensityr) = ln.zSpiralSpot(hx,hy,3,spirals,rays)
(xi,yi,zi,intensityi) = ln.zSpiralSpot(hx,hy,4,spirals,rays)
(xz,yz,zz,intensityz) = ln.zSpiralSpot(hx,hy,5,spirals,rays)
fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111)
ax.set_aspect('equal')
ax.scatter(xu,yu,s=5,c='blue',linewidth=0.35,zorder=20)
ax.scatter(xg,yg,s=5,c='green',linewidth=0.35,zorder=21)
ax.scatter(xr,yr,s=5,c='red',linewidth=0.35,zorder=22)
ax.scatter(xi,yi,s=5,c='magenta',linewidth=0.35,zorder=23)
ax.scatter(xz,yz,s=5,c='yellow',linewidth=0.35,zorder=24)
ax.set_xlabel('x');ax.set_ylabel('y')
fig.suptitle('Spiral Spot')
ax.grid(color='lightgray', linestyle='-', linewidth=1)
ax.ticklabel_format(scilimits=(-2,2))

plt.show()



In [14]:
def many_spots(ln, hxs,hys,wavenum=1,spirals=10,rays=600):
    fovxs, fovys, xs, ys = np.array([]), np.array([]), np.array([]), np.array([])
    for hx, hy in zip(hxs,hys):
        (x,y,z,intensity) = ln.zSpiralSpot(hx,hy,wavenum,spirals,rays)
        fovxs, fovys, xs, ys = np.append(fovxs,hx*np.ones((len(x),1))), np.append(fovys,hy*np.ones((len(y),1))), np.append(xs,x), np.append(ys,y)
    return fovxs, fovys, xs, ys

In [15]:
hxs, hys = np.linspace(-1.75,1.75,5), np.linspace(-1.75,1.75,5)
[HXs,HYs] = np.meshgrid(hxs,hys)
hxs, hys = HXs.flatten(), HYs.flatten()
fovxu, fovyu, xu, yu = many_spots(ln, hxs, hys, wavenum=1, spirals=10, rays=600)
fovxg, fovyg, xg, yg = many_spots(ln, hxs, hys, wavenum=2, spirals=10, rays=600)
fovxr, fovyt, xr, yr = many_spots(ln, hxs, hys, wavenum=3, spirals=10, rays=600)
fovxi, fovyi, xi, yi = many_spots(ln, hxs, hys, wavenum=4, spirals=10, rays=600)
fovxz, fovyz, xz, yz = many_spots(ln, hxs, hys, wavenum=5, spirals=10, rays=600)

fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111)
ax.set_aspect('equal')
ax.scatter(xu,yu,s=5,c='blue',linewidth=0.35,zorder=20)
ax.scatter(xg,yg,s=5,c='green',linewidth=0.35,zorder=21)
ax.scatter(xr,yr,s=5,c='red',linewidth=0.35,zorder=22)
ax.scatter(xi,yi,s=5,c='magenta',linewidth=0.35,zorder=23)
ax.scatter(xz,yz,s=5,c='yellow',linewidth=0.35,zorder=24)
ax.set_xlabel('x');ax.set_ylabel('y')
fig.suptitle('Spiral Spot')
ax.grid(color='lightgray', linestyle='-', linewidth=1)
ax.ticklabel_format(scilimits=(-2,2))

plt.show()



In [16]:
hxs, hys = np.linspace(-1.75,1.75,10), np.linspace(-1.75,1.75,10)
[HXs,HYs] = np.meshgrid(hxs,hys)
hxs, hys = HXs.flatten(), HYs.flatten()
fovx, fovy, x, y = many_spots(ln, hxs, hys, wavenum=1, spirals=10, rays=60)
fov = np.sqrt(fovx**2 + fovy**2)

fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111)
ax.set_aspect('equal')
plt.scatter(x,y,s=5,c=fov,linewidth=0.35,zorder=21)
plt.xlabel('x [mm]')
plt.ylabel('y [mm]')
cbar = plt.colorbar()
cbar.set_label('FOV [degrees]')
plt.grid(color='lightgray', linestyle='-', linewidth=1)
#ax.ticklabel_format(scilimits=(-2,2))
plt.axis([-600,600,-600,600])

plt.show()



In [1]:
# Spot diagram analysis functions
def zGridSpot(ln, hx, hy, waveNum, dx, dy, mode=0):

    pxs = np.arange(-1.0,1.0,dx)
    pys = np.arange(-1.0,1.0,dy)
    [PXs,PYs] = np.meshgrid(pxs,pys)
    pxs, pys = PXs.flatten(), PYs.flatten()
    
    x = [] # x-coordinate of the image surface
    y = [] # y-coordinate of the image surface
    z = [] # z-coordinate of the image surface
    intensity = [] # the relative transmitted intensity of the ray
    for px, py in zip(pxs,pys):
        rayTraceData = ln.zGetTrace(waveNum, mode, -1, hx, hy, px, py)
        if rayTraceData[0] == 0:
            x.append(rayTraceData[2])
            y.append(rayTraceData[3])
            z.append(rayTraceData[4])
            intensity.append(rayTraceData[11])
        else:
            print("Raytrace Error")
            exit()
            # !!! FIX raise an error here
    return (x, y, z, intensity)

def many_grid_spots(ln, hxs, hys, dx, dy, wavenum=1):
    fovxs, fovys, xs, ys = np.array([]), np.array([]), np.array([]), np.array([])
    for hx, hy in zip(hxs,hys):
        (x,y,z,intensity) = zGridSpot(ln,hx,hy,wavenum,dx,dy,mode=0)
        fovxs, fovys, xs, ys = np.append(fovxs,hx*np.ones((len(x),1))), np.append(fovys,hy*np.ones((len(y),1))), np.append(xs,x), np.append(ys,y)
    return fovxs, fovys, xs, ys

hxs, hys = np.linspace(-1.75,1.75,10), np.linspace(-1.75,1.75,10)
[HXs,HYs] = np.meshgrid(hxs,hys)
hxs, hys = HXs.flatten(), HYs.flatten()
dx = 0.1
dy = 0.1
fovx, fovy, x, y = many_grid_spots(ln, hxs, hys, dx, dy, wavenum = 1)
fov = np.sqrt(fovx**2 + fovy**2)
print x, y


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-3e7bbb87013a> in <module>()
     31     return fovxs, fovys, xs, ys
     32 
---> 33 hxs, hys = np.linspace(-1.75,1.75,10), np.linspace(-1.75,1.75,10)
     34 [HXs,HYs] = np.meshgrid(hxs,hys)
     35 hxs, hys = HXs.flatten(), HYs.flatten()

NameError: name 'np' is not defined

In [ ]:
filename = os.path.join(plotDir,'spots.dat')
fid = open(filename,'w')
for a,b,c,d in zip(fovx,fovy,x,y):
    fid.write('%.5f %.5f %.5f %.5f\n'%(a,b,c,d))
fid.close()