How to debug a ZPL macro

Zemax Programming Language (ZPL) is a powerful programming language. While it is easy to use, the user is responsible for error-checking, debugging code logic and for good programming practice. This article explains good practice and gives some helpful tips on how best to write and debug your ZPL macros.

Authored By Mark Nicholson


The Zemax Programming Language (ZPL) is a powerful programming language that allows users to access OpticStudio's functionality in order to make repetitive tasks and analysis easier to work through. It is straightforward to use, but can be used for a myriad of unique applications. For this reason, any technical support on macro writing is restricted to ensuring that all ZPL functions and keywords work as documented. (If you find that a keyword is not working as stated, please forward your code snippet to

Because Zemax support cannot write or debug your program for you, we recommend working through this article in which we set out some guidance on good programming practice, and tips for writing good ZPL code.

How to debug your ZPL macros

The following advice will help you write well-structured macros:

1. Test each section of the macro as you write it.

2. Use a debug control parameter. Code like this is very useful:

debug = 1 #Set debug = 0 to prevent printing information messages 

# or <>0 to print messages

IF (debug) THEN PRINT "hello"  # for example

Instead of printing "hello", you can of course print out a variable, etc. But, by changing a single parameter, the value of the variable debug, from 0 to any number other than 0, you can turn the printing of information messages on and off. This makes it much easier to debug a complex macro. You can have as many IF (debug) THEN lines as you want throughout your code, and can then turn error reporting on and off with just one variable.

3. Always restore your design to its starting point, unless you specifically intend the macro to change the lens file. For example, lets say you write a macro to print out a CAM table for a zoom lens. The macro must change configurations. You should always restore the original configuration, with code like:

orig_config = CONF()  # Get the configuration number 

# when the macro starts

{write your code here....change configurations, get data, print etc...}

SETCONFIG orig_config # restore the starting configuration.

The same applies if your macro changes the value of any wavelengths, field points, aperture, temperature etc. Unless you specifically intend the macro to permanently change the file, always restore the starting data after any changes, or have the macro close the lens file after execution without saving changes. Your macro can also save the file at any intermediate stage.

4. Your macro can change anything in your lens file, but nothing will actually happen until you execute an UPDATE keyword. This lets the macro make as many changes as it needs to, and then all changes are implemented at one time.

5. Write plenty of comments, so you remember what your macro does when you next run it in six months time!

6. ZPL is not case sensitive, but it is helpful to write your own variables in lower case, and to write any ZPL keywords or functions in uppercase.

7. Check for raytrace errors. When you call the RAYTRACE keyword, check the value of RAYE() to ensure that the ray traced successfully, and did not (for example) TIR or hit an aperture

8. Use variables when calling keywords. This is much easier to read and debug:

hx = 0

hy = 1

px = 0.2

py = -0.5

wavelength = 1

RAYTRACE hx, hy, px, py, wavelength


RAYTRACE 0 1 .2 -.5 1

9. If you intend your macro to be used with more than one Zemax file, avoid hard-coding surface numbers, wavelength numbers, field numbers etc. Use the functions NSUR(), NWAV(), PWAV() etc so this data is extracted at run time.

10. Always validate user input. For example, if you write:

INPUT "Enter the wavelength number", wavelength

so that a dialog box opens and the user enters the wavelength number, perform checks like

IF (wavelength > NWAV()) THEN wavelength = NWAV()

IF (wavelength < 1) THEN wavelength = 1

or similar afterwards so that the entered data is always checked to be valid.


Was this article helpful?
0 out of 0 found this helpful



Article is closed for comments.