Optimization using a ZPL Macro: the ZPLM operand

This article is part of the ZPL Programming free tutorial.

This article explains how ZPL macros can be used to define complex optimization targets in the Merit Function Editor through use of ZPLM optimization operand. As an example, the article describes how ZPLM can be used to constrain the center of mass of a system to ensure it is correctly balanced.

Authored By Alessandra Croce


Article Attachments


OpticStudio has almost 400 operands to target nearly any value of interest, including math operands such as SINE, PROD, SQRT, etc. that allow for the definition of elaborated merit functions. Sometimes, however, a needed value requires complex calculations that would be impractical to perform inside the merit function editor. In such cases, you can use optimization operand ZPLM, which executes a macro to determine the value of an operand. The macro runs and returns the value back to the merit function using OPTRETURN keyword.

The ZPLM operand

ZPLM operand has six arguments: Mac#, Data, Hx, Hy, Px, Py

  • Mac# is the macro number OpticStudio should execute. Macro to be used with ZPLM operand should be saved as ZPLnn.zpl, where 00 ≤ nn ≤ 99.
    • For example, Mac# should be 3 for ZPLM to call macro ZPL03.zpl
  • Data is the data value computed by the macro. Up to 51 data values may be computed in single macro (0 ≤ Data ≤ 50). For efficiency, the macro will be executed only when Data = 0; otherwise data from previous macro call is used (i.e. Data = 0 always needs to be called at least once)
  • Hx, Hy, Px, and Py are values that can be passed to the macro to use in its computation. They don’t have to be normalized field/pupil coordinates:


The following example will illustrate the definition of a macro to be used with ZPLM optimization operand.

ZPLM example: Center of Mass constraint

In some optical systems (riflescopes, binoculars, tripod mounted cameras, etc.), the center of mass is an important mechanical consideration. Imagine we were designing a riflescope and one constraint was to make the system balanced. This means, the center of mass (CM) should be halfway between front element and rear element.

Load sample file <Documents>\Zemax\Samples\Sequential\Afocal\Afocal Riflescope.zmx


For the purpose of this example, we will make a few simplifying assumptions:

  • All lenses are rotationally symmetric
  • All materials are homogeneous
  • CM of each lens is located halfway between vertices (strictly speaking, this is only true for lenses with equal and opposite curvatures)
  • Surface 1 is the global coordinate reference (GCRS)

To constrain the location of the center of mass we need:

  • The global position of each element
  • The mass of each element
  • The total system length (front lens to rear lens)

We will therefore use the following ZPL functions and keywords:

  • GLCZ() function to return the surface global z-coordinate
  • OPEV() function to retrieve the mass of the elements using TMAS optimization operand
  • GETSYSTEMDATA keyword to return the total track length (surface 1 to image plane)
  • OPTRETURN keyword to return data to the macro

ZPLM macro code

The Center of Mass macro, which can be found in the Article Attachments, looks like this:


Save the macro as ZPL01.ZPL, so that it can be called with Mac# = 1

ZPLM in the merit function

In the merit function add a ZPLM operand with Mac# = 1, Data = 0. This will run the macro and return the center of mass of the system.


Only one value is returned here. To return additional values, simply add extra OPTRETURN lines to your macro:

OPTRETURN data_number, value

In this example we will not optimize, but the process is the same as with other operands (i.e. set the desired target and a non-zero weight). Note that the units of the value returned by macro can be anything, so the ZPLM operand weight will need to be considered to accurately convey the importance of this target with respect to the others listed in the merit function. This macro in particular requires a very small weight to balance ZPLM with other operands targeting system performance.

As previously explained, ZPLM allows the use of up to four values (Hx, Hy, Px, Py) to pass data to the macro. The passed values can be accessed in macro with PVHX(), PVHY(), PVPX(), PVPY() numeric functions. In this example we could pass barrel CM location and mass to the macro to account for CM of barrel and lenses combined.

  • Hx = barrel CM to system center distance
  • Hy = barrel mass

Modify the macro as below, and save the modified macro as ZPL02.zpl


In the merit function, set Mac# = 2, enter the values for barrel CM location (Hx) and mass (Hy) and note the change in data values reported:


Remember: the macro is only executed when Data = 0 to speed up merit function evaluation.

This article is the last part of the ZPL Programming free tutorial.

Previous article: How to create a user-defined solve


Was this article helpful?
4 out of 5 found this helpful



Article is closed for comments.