2. OpticsTalk Overview
• Introductions
Name, company, experience with ZPL or programming in general, and what you’re hoping
to get out of this talk
• What is ZPL?
• In-depth examples and discussion
3. About me: Alexandra Culler
• Optical Engineer with the Customer Success team at Zemax
Responsible for providing technical support and creating
knowledgebase content to help users make the most of their
Zemax products
• Joined Zemax in January 2019
• M.Sc. in Applied Physics from University of Oregon
4. About me: Julia Zhang
• Optical Engineer at Zemax China
• Responsible for technical support and public training course
in APAC, help customers with problems of modeling and
analyzing optical systems in OpticStudio
• Joined Zemax in August 2017
• M.Sc. in Physics at Tongji University
5. Zemax Programming Language
• ZPL is a simple programming language written to mimic BASIC
• Not case-sensitive
• ZPL is an interpreted language: the code is read and executed line-by-line with no
pre-compiled guidance
• Includes loops, variables, arrays, and basic mathematic functions
Also allows the ability to call a “function file” via CALLMACRO
6. ZPL-Specific operations
• ZPL operates through its own set of keywords and numeric functions
Keywords make a change to the file
Numeric and string functions extract information about the system
7. When to use the ZPL
• When you need a unique format for data
• To implement features or calculations not in the program, such as data retrieval,
export, or simple plotting
• To optimize when there is no appropriate operand (custom operand creation)
• To create custom/complex solves (custom solve creation)
• To automate repetitive keyboard activity
8. Discussion
• Any other purpose of using ZPL macro to accomplish a specific task? What is your
experience using ZPL?
• What macros have you written? How frequently do you use it? Should we add it to
OpticStudio or to the Knowledgebase?
• Some tricks to share? (SOSO, GOSUB, etc..)
• We have a new learning path on the ZPL. What other help or examples would you
like to see?
• Let’s go through some examples! Each will be posted to the OpticsTalk forum post.
9. To implement features or calculations
not in the program…
• Example: Calculate the angle of incidence (AOI) for all rays across the pupil at a
given surface
Can be used to check for high AOI which would indicate a very sensitive optic (difficult to
manufacture at low cost)
• What we need:
A method to calculate AOI
A way to calculate the AOI for multiple rays
• The optimization operand RAID will calculate the Angle of Incidence for a
particular field and pupil coordinate, at a given surface, for a specific wavelength
10. AOI analysis: Procedure
1. Choose the surface, number of rays to trace in X and Y across the pupil, and
wavelength of interest.
2. To assess across all fields, declare an array to hold the field data.
3. Find the maximum field in the system for calculation of Hx and Hy.
4. Use a nested FOR loop to cycle through fields (1), X-direction (2), Y-direction (3).
5. Use optimization operand RAID to report the incident angle.
12. Can we clean this up?
• Instead of hard-coded inputs, ask the user for the surface, step number, and
wavenumber of interest.
• Instead of a nested FOR loop, use CALLMACRO
CALLMACRO gives us the ability to call a second (child) macro from within the first (parent)
CALLMACRO is analogous to calling an external function file. We typically save common
tasks to function files for use later.
• Data may be passed back and forth between the parent and child macros using
the keywords CALLSETDBL and CALLSETSTR and the functions CALD and
$CALLSTR
• More information:
The Programming Tab > About the ZPL > Calling a Macro from within a Macro
https://my.zemax.com/en-US/Knowledge-Base/kb-article/?ka=KA-01473
13. Update the macro
• Global variables (to be passed to the child macro):
Surface number, wave number, number of rays (numSteps), hx, hy, and the operand of interest
• Child macro will now be used to walk across the pupil for any operand which has the same
properties as RAID:
14. Questions and discussion
• We could use this for optimization. If we want to avoid the TIR error message, we
can search for cases in which RAID is “0”. That may allow us to figure out what
operands we can eliminate to allow the optimization to continue.
• Can we output the data directly to Excel, instead of copying? Yes! Use OUTPUT to
print directly to a CSV vile, and use $TAB() as delimiter.
• Can we use this to find maximum AOI? Sure! We could store the RAID results to an
array for that purpose.
• What are your thoughts?
15. To optimize when there is no
appropriate operand…
• Example: Footprint diagram operand for returning the max Y landing coordinate
for a particular surface
Right now, there is no operand which will report this value
• What we need:
A way to access this value
• The value is provided in the Text tab of the Footprint Diagram. This means it is able
to be extracted with the keyword GETTEXTFILE
16.
17. Custom operand: Procedure
1. Create a temporary file to save the Footprint Diagram text output. Create a
variable to hold the value of interest.
2. Open the file and cycle through the “header” data until we reach the line of
interest.
3. Save the line of interest and truncate so that only the numeric data is retained.
4. Convert the string to number.
5. Close the temporary file and delete it.
6. Report as the “Value” output for the operand.
18. Can we make this more generic?
• Use the LABEL and GOTO commands to create a Switch statement
A switch statement allows the value of a variable or expression to change the control flow
of program execution via search and map.
In other words, we will run the statement’s command until a particular variable value
“breaks” us out of that cycle
Lines 18 and 19 will continue to be
executed until the IF statement at line 20
or line 21 is TRUE.
If line 20 is TRUE, then we will “break” from
the loop and move to line 27
Now, we don’t need to know how many
lines to skip before we reach the line of
interest
19. Questions and discussion
• What is EOFF() doing? This is an end of file flag with a Boolean output. It will return
1 if the end of the file has been reached, otherwise, it will be 0. Only valid after the
execution of a READ or READSTRING keyword.
• Converting between string values and numeric values: SVAL(A$), $STR(expression)
$STR() is coming up in our next example. It is useful for generating files which are named
based on the current iteration value of a FOR loop.
When we convert from number to string, we can use FORMAT and INTE(). This will help us
avoid things like “1.000.txt” or “1.1.txt”.
• What are your thoughts?
20. To automate repetitive keyboard
activity…
• Example: Apply the Make Thermal tool to Monte Carlo files
Without the ZPL, we would need to open every Monte Carlo file and run the tool by hand
With the ZPL, we can automate opening each file and modifying the Multi-Configuration
Editor
• What we need:
Open each MC file and apply Make Thermal
Currently, there is no ZPL keyword to apply Make Thermal. We will need to manually apply
the operands to the Multi-Configuration Editor
• We can use the keywords LOADLENS to open the MC files. We can use the
keyword SETMCOPERAND to update Multi-Configuration operands
21. Apply Make Thermal: Procedure
1. Enter number of configs, min, and max temperature.
2. Set up the format of the MC files to be opened.
a. Discussed in more detail: https://my.zemax.com/en-US/Knowledge-Base/kb-
article/?ka=KA-01485
3. Open an MC file for editing.
4. Clear the Multi-Configuration Editor.
5. Insert new configurations based on the input configNUM
6. Apply each standard operand (Radius, Thickness, Clear Semi-Diameter, Chip
Zone, Mechanical Semi-Diameter).
7. Apply the Thermal Pickup solves.
8. Update lens, and save output.
22. Can we expand the functionality?
• The coefficients for Even Aspheres will have additional Multi-Configuration
operands than the standard ones already added. We can check for the surface
type with the BUFFER command.
• $BUFFER():
Numeric Functions will return numeric values (marked as black in the ZPL)
Occasionally, certain settings for some Numeric Functions will return a string value. In that
case, the string is placed in the “buffer”. To extract it, use the String Function $BUFFER()
23. Update the macro
• Add a Numeric Function which checks on surface properties. Use this Numeric Function to
pull the Surface Type. Use $BUFFER() to return the string.
• Add an IF statement to check for an Even Asphere. If one exists, add and edit more Multi-
Configuration operands
24. Additional Discussion Points
• Similar one is used for ZPL solve, SOSO(). The function returns the surface number
and/or object number of the macro currently being executed as a solve. The
function is very useful if we want to include parameter of the surface, but we have
no idea of the surface number in advance until we decide to add ZPL solve for the
certain surface.
• SURC(A$), SRCN(A$, n)- tag a specific surface if the surface comment matching A$
or if nth surface comment matching A$.
SCOM(A$, B$), If the strings are equal, SCOM returns 0.
• CALLMACRO can be used to call child macro in current executed parent macro. If a
subroutine is used several times within one macro, we can use SUB to define the
subroutine, and use GOSUB to direct the program flow to the defined subroutine.
25. OpticsTalk Feedback
• Thank you for attending! Please continue the discussion, post questions, or give
advice about your experience with the ZPL at the corresponding forum post.
• Some additional examples (and anything we didn’t get to) will be posted in the
forum as well!
• Look out for a survey about this talk. We greatly appreciate your feedback!