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

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

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

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

In [5]:
ln.zLoadFile(zfile)


Out[5]:
0

In [6]:
# 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	           -750	                     	      4382.059	              0	 Middle TEA Baffle
  25	 EVENASPH	          -6788	            750	               MIRROR	          3420	         -0.222	 M2
  26	 STANDARD	       Infinity	       5377.191	                     	      3885.042	              0	 M2 Baffle Bottom
  27	 STANDARD	       Infinity	          233.8	                     	      5518.465	              0	 M1/M3 Offset
  28	 EVENASPH	        -8344.5	        -3630.5	               MIRROR	          5016	          0.155	 M3
  29	 STANDARD	       Infinity	     -0.7725882	                     	      1808.696	              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 [7]:
# General System properties
ln.zGetSystem()


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

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


Out[8]:
firstOrderData(EFL=10171.99814, paraWorkFNum=1.216746189, realWorkFNum=1.218277895, paraImgHeight=310.7826513, paraMag=0.0)

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


Paraxial magnification : 0.0
Real working F/#       : 1.218277895
Effective focal length : 10171.99814
Paraxial working F/#   : 1.216746189
Paraxial image height  : 310.7826513

In [10]:
# ... 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[10]:
systemAper(apertureType=0, stopSurf=22, value=8360.0)

In [11]:
# ...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 [12]:
# 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 [17]:
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()