Talking to ZEMAX from Python using PyZDDE

This article describes:
  • How to use PyZDDE to communicate between Zemax and Python
  • The three modes of operation of PyZDDE using examples
  • Brief description of the PyZDDE toolbox, and few use cases
 
Indranil Sinharoy (Lyle School of Engineering, Southern Methodist University, TX)
01/22/2014
Programming Zemax

Python has rapidly become a dominant alternative to MATLAB not just because of the economic advantage, but because it a powerful scripting language, easy to learn and has a highly active scientific-software ecosystem supported by the open-source community. PyZDDE is a Python based toolbox for communicating with ZEMAX using the DDE messaging protocol. It has all the functions for accessing ZEMAX using the data-items defined in the “ZEMAX EXTENSIONS” chapter of the manual. It can be used to link 32/64- bit ZEMAX and 32/64- bit Python, establish multiple simultaneous DDE channel objects for communicating with multiple ZEMAX DDE servers, and execute ZPL macros over the DDE link. The toolbox can also be used for documentation, sharing and teaching of optical design process with ease (enabled by IPython notebooks). It can be used mainly in 3 different ways as demonstrated in the following sections.

ZEMAX-Python communication in scripting mode
PyZDDE can be used with regular scripts by importing the module into a source file. As an example, Table 1 lists a simple Python script for plotting spiral spot diagram using ZEMAX.
 
# Example script using PyZDDE to plot spiral spot
 
import matplotlib.pyplot as plt   # import plotting module
import pyzdde.zdde as pyz         # import pyzdde module          
 
# A ZEMAX lens design file with full pathname, for example
zmf = 'C:\\ZMXFILES\\Cooke 40 degree field.zmx'
 
# Create a PyZDDE object
ln = pyz.PyZDDE()
 
# Initiate the DDE link
status = ln.zDDEInit()
 
# Load the lens file into the ZEMAX DDE server
ret = ln.zLoadFile(zmf)
 
# Set ray tracing parameters for creating the spiral spot
hx, hy =  0.0, 0.4
spirals, rays = 25, 1000
wavenum = 3
 
# spiralspot function returns the coordinates of the spots at the image plane
x, y, _, _ = ln.zSpiralSpot(hx, hy, wavenum, spirals, rays)
 
# close the DDE channel
ln.zDDEClose()
 
# Create a Matplotlib figure
fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111)
ax.scatter(x, y, s=8, c='#2171b5', linewidth=0.3)
 
# Figure decorations
ax.set_aspect('equal')
ax.set_xlabel('x', fontsize=14)
ax.set_ylabel('y', fontsize=14)
ax.set_title('Spiral Spot')
ax.grid(color='lightgray', linestyle='dotted', linewidth=1.0)
ax.ticklabel_format(scilimits=(-2,2))
         
# Call show to display the figure
plt.show()
 
Table 1: A simple script to plot spiral spots


 
Figure 1: Spiral spot
 
Interactive mode communication between Python and ZEMAX

Much like the MZDDE toolbox, PyZDDE can be used interactively using a Python interactive shell. One of the best interactive Python shell is the IPython shell,QtConsole. Figures 2 (a) – (e) are screenshots of (a contrived) Python-ZEMAX interactive communication session. Comments are placed beside most of the commands to further explain their function.
 

Figure 2 (a): Interacting with ZEMAX from IPython QtConsole’s interactive environment. The figure also shows the help text (docstring for the function) popup when typing is paused for a few seconds after typing the opening parentheses.
 

Figure 2 (b): Interacting with ZEMAX from IPython QtConsole’s interactive environment. 
 

Figure 2 (c): Interacting with ZEMAX from IPython QtConsole’s interactive environment. 
 
ZEMAX comes with a huge set of operands and button codes. PyZDDE enables quick look-up of all operand and button codes. Operands and buttons may also be found using keyword search as shown in Figures 2 (d) – (e). These functions can be executed within an interactive environment without creating any pyzdde object (DDE communication channel), and hence can be used even if PyZDDE is not being used for communicating between Python and ZEMAX.
 

Figure 2 (d): Interacting with ZEMAX from IPython QtConsole’s interactive environment. This figure shows a listing of the tolerance operands produced by the command showZOperandList() in the interactive environment.   
 

Figure 2 (e): Interacting with ZEMAX from IPython QtConsole’s interactive environment. 
 
Calling ZEMAX from IPython Notebook

The IPython notebook, which too is interactive, is a computing environment that is similar to Mathematica notebooks. The ability to interact with ZEMAX from an IPython notebook can be a very useful for both teaching and documentation. Some of these concepts are shown in Figures 3(a) – (f). The examples, though highly contrived, illustrate the simplicity and utility of PyZDDE within the notebook environment.
 

Figure 3 (a): Interacting with ZEMAX from IPython Notebook environment. 
 

Figure 3 (b): Interacting with ZEMAX from IPython Notebook environment. The exact content of the figure is determined by the settings of each of the analysis windows within ZEMAX. PyZDDE just grabs the analysis window put out by ZEMAX and displays it as best as possible within the IPython shell or notebook.      
 

Figure 3 (c): Interacting with ZEMAX from IPython Notebook environment. 
 

Figure 3 (d): Interacting with ZEMAX from IPython Notebook environment. 
 

Figure 3 (e): Interacting with ZEMAX from IPython Notebook environment. 
 

Figure 3 (f): Interacting with ZEMAX from IPython Notebook environment. 
 
Brief description of PyZDDE toolbox

Currently, all the functions (126 in total) for accessing the ZEMAX using “data items” have been implemented. In addition, there are few utility functions.

There are 4 types of functions in the toolbox:
 
  1. Functions for accessing ZEMAX using the data items as defined in the “ZEMAX EXTENSIONS” chapter of the ZEMAX manual. These functions’ names start with “z” and the rest of the function names match the data item defined by Zemax. For example zGetSolve, zSetSolve, etc.
  2. Helper functions to enhance the toolbox functionality beyond just the data items, such as zLensScale, zCalculateHiatus, zSpiralSpot. Also, there are other helper functions which increase the capability of the toolbox such as zOptimize2, zSetWaveTuple, etc. More functions are expected to be added over time.
  3. Few functions such as ipzCaptureWindow, ipzGetTextWindow can be used to embed analysis and graphic windows and text files from Zemax into an IPython Notebook or IPython QtConsole.
  4. There are several other functions that do not require communication with Zemax. Examples include showZOperandList, findZOperand, findZButtonCode, etc. These functions may be used without ZEMAX running. Also, more functions are expected to be added over time.
This article doesn’t describe the details of communication between ZEMAX and other external software through the DDE framework. This process is described in the “ZEMAX EXTENSIONS” chapter of the ZEMAX manual in the blog post “Accessing ZEMAX from Python using PyZDDE”.

Downloading and using PyZDDE

The PyZDDE toolbox, which comes with a MIT License, can be downloaded (or cloned or forked) from github host site at https://github.com/indranilsinharoy/PyZDDE. The github wiki also has simple instructions on downloading and quickly setting up a working system in the “Getting Started” article.    

Final thoughts

PyZDDE is a work in progress. I would like to request and welcome interested folks to use, improve and contribute to the further development of PyZDDE in a truly open-source way.

Author Bio

Indranil Sinharoy is currently pursuing a PhD in EE at SMU, Dallas, Texas. He is a member of the Photonics Architecture lab under Dr. Marc Christensen. His areas of research are computational imaging, signal processing and computer vision. He enjoys programming in Python and photographing. Prior to joining his PhD program, he was an embedded software engineer at LSI Logic and Magnum Semiconductors. More details about his work, interests and thoughts can be found at http://indranilsinharoy.com/.