OpticsTalk: Advanced ZPL macro programming

  • 17 August 2020
  • 10 replies

Userlevel 2
Badge +1

This forum thread is the discussion space for the OpticsTalk: Advanced ZPL macro programming, hosted by Alexandra Culler.

ZPL macros are a convenient way to expand the functionality of OpticStudio. In this talk, we will present several examples of advanced ZPL code and we will introduce useful commands such as CALLMACRO, LABEL, and BUFFER. Finally we will discuss methods for simplifying large or complex macros. 

Have questions? Post them here before the talk!

10 replies

Userlevel 6
Badge +4

So, Nicholas . . .   What is an OpticsTalk and how does one listen to it?



Userlevel 6
Badge +2

Hi David,

The OpticsTalks are small, informal technical talks led by a Zemax engineer. Generally, the Zemax engineer will start the talk off with a presentation on the topic, and leave the rest of the hour for discussion or examples. To ensure that discussion can flow freely, we do not record the sessions, so you have to register to be able to listen in. Upcoming OpticsTalks are listed here: https://my.zemax.com/en-US/customer-events/. A registration link will appear a couple of weeks before the date of the talk. 

Each talk has a corresponding forum post. We use these posts to share the slides and examples, or to continue discussion. I will post the slides for tomorrow's talk here soon!

Registration for tomorrow's talk is closed now, but I could see if there's some extra space. Are you interested in attending?


Userlevel 6
Badge +4

Thanks, Allie. I can pass on this one. But I'll keep an eye out for future talks. 



Userlevel 6
Badge +2

Good afternoon,


I am attaching the slides for the talk later this evening, as well as the sample files and macros. The talk will be structured in the following way:

  • Introductions
  • A general overview of ZPL
  • Examples, presented with:
    • Use case
    • Procedure for the code
    • Results
    • Updates we could make for efficiency/generalization

Julia and I will attach other sample macros here once the talk is complete. I encourage everyone to use this space to share ideas and advice. Julia and I will be monitoring this thread, so please feel free to continue your discussions or ask questions here as well!


Update: The RAID analysis macro can now be found on the Code Exchange here: ZPL Macro: Read optimization operand across pupil | Zemax Community

Update: The Make Thermal macro is now found in the Code Exchange. Updates to the macro will be provided at that location: ZPL Macro: Apply Make Thermal tool to Monte Carlo files | Zemax Community





Userlevel 6
Badge +2

Following the talk yesterday, I am posting some other sample macros.

For Ciaran:

I am adding a couple of samples in a ZIP drive titled 'DataManipulation.ZIP'. These will exemplify how we can manipulate Text window data through the ZPL. There are three samples:

  1. Detector FWHM: This macro saves the Text tab of a Detector Viewer window with GETTEXTFILE. Then, we skip the header data and begin saving the numeric data to an array. This array is used to calculate FWHM ane e-squared.

  2. Huygen's Data to Array: This macro is similar to the first, except the numeric function GETL is used instead of GETTEXTFILE. GETL will extract data from the Text tab of an analysis window but the window must be opened and must be opened to the Text tab for this to work. 

  3. Ray Landing Coords: This macro saves the output of a Ray Database window and saves the x,y,z coordinates for each segment. This is similar to macro #1, but shows how we can use the READ keyword to store data as numeric values instead of as strings

For Adam:

I found an old macro I wrote which is a simplified version of Example 3 from yesterday. You may find it in the ZIP drive 'Case1909_Manually add stepwise compensation to MC files.zip'. This macro was intended to emulate a step-wise compensator. For example, an optic may be placed in a holder which may be tilted at discrete angle values. If we are only allowed to tilt the optic for a small set of angles, then using one of the built-in compensators will not work, as those will be made 'Variable' and be allowed to change continuously as the system is optimized. 

In this sample, Monte Carlo files are being opened, the tilt of an optic is modified, and the Merit Function value is reported. I have formatted the output so that it mimics the output of the 'Monte Carlo' section of a tolerance analysis. 

Additional example:

This example was provided by my colleague Michael Humphreys. Here is his description:

I'm creating a ZPLM that controls the beam vignetting on a folded system. 



One of the difficulties of the ZPLM is having enough fields to pass all the data that I want to work with.  If I want to pass in the pupil coordinates for a specific ray into the ZPLM, I typically have to use 2 columns, a PVHX() and a PVHY(), which only leaves 2 more columns for data.  


Using the same thinking as a non-sequential pixel (NSDD), you can easily convert from the 2 values Px/Py to a single 'pixel' value which represents the pupil coordinate and then use only 1 column rather than 2.  

Userlevel 4
Badge +2

Additional example on plotting real entrance pupil in 3D layout.


This example was provided by my colleague Michael Cheng. Here is a description on this macro:



For wide angle system, it’s incapable to visualize the position and the size of a real entrance pupil in different field angles. With running this macro, real ray trace being did for capturing entrance pupil information for different field angles. The macro assumes axial-symmetric, only y field and the field angle in object is positive. Ray-Aiming should be turned on to correctly run this macro. Probably it can only worked with field type Angle and Object Height.



How to use:  Just run the macro, and open 3D Layout with showing central field and all configs.



Sample file: Wide angle lens 210 degree field.zmx 




Update: The ZT_ENP analysis macro can now be found on the Code Exchange here: 


Userlevel 7
Badge +3

Michael's macro is brilliant. Thank you for posting this! It's a real help in understanding how wide-angle lenses work, and also for any system with field as the real pupil always shifts with field but it's hard to visualize. I think better visualization of the pupil, especially with field but also with wavelength, would be a great addition to the code. 

Userlevel 7
Badge +3

BTW, here's the same lens, with the layout drawing settings reconfigured to show the evolution of the pupil more clearly. Excellent!


Userlevel 1

This macro is cool, however I'm a little confused about the jargon 'pupil' . A lens has one entrance pupil, as far as I know. now matter where off axis.Anybody help me with that?

Userlevel 7
Badge +3

Hi Steven,

The entrance pupil is usually virtual and is an image of the stop surface as seen through the optics between the object and the stop. As such, the pupil changes size and position with both wavelength and field. It is also aberrated by the optics in front of the stop.

In paraxial optics, we usually take 'the' entrance pupil as being the paraxial image of the stop on-axis, and at the primary wavelength. However the real pupil will be aberrated with respect to that, and the pupil will shift with field and wavelength. In wide angle systems, the wide-angle lens works specifically because the pupil moves forward (towards the object) and rotates, otherwise you could not get an imaging systen with a field of view greater than 90 degrees!

Hope that helps,

- Mark