How to Determine Perturbation Values in a Monte Carlo Tolerance...


This article describes how to determine the perturbation values assigned by Zemax during a Monte Carlo tolerance analysis.

Authored By: Sanjay Gangadhara

Introduction

Tolerance analysis is an important part of any optical design. Such an analysis allows the designer to determine the sensitivity of the system to errors introduced during manufacturing and assembly.

In Zemax, possible errors may be introduced to the system individually (Sensitivity) or simultaneously (Monte Carlo). More information on these different types of tolerance analysis may be found in the chapter of the Zemax manual entitled “Tolerancing”, as well as in the Knowledge Base article entitled “How to Perform a Tolerance Analysis”.

During Sensitivity analysis, Zemax reports the magnitude of the individual perturbation and the corresponding change to the system criterion (e.g. RMS spot radius). During Monte Carlo analysis, however, Zemax only reports the change in the system criterion, since in this case all perturbations are considered simultaneously.

In most cases, the user is not interested in the individual perturbation values during a Monte Carlo analysis; usually, the goal of the analysis is to determine the variation in system performance that arises from the simultaneous application of tolerance errors in a statistical fashion. However, there may be times when it is useful to know the values for the individual perturbations in the Monte Carlo analysis, for example when some set of perturbations could be used to enhance system performance.

Although Zemax does not report the individual perturbations in a Monte Carlo analysis, this information is available to the user if the Monte Carlo files are saved. The user could simply open each Monte Carlo file in turn to determine the perturbations that were applied in that run.

For a large number of Monte Carlo runs – with an associated large number of files – this process would be tedious. However, the process can be automated using a ZPL macro. In the Knowledge Base article entitled “How to Open Consecutively-Named Lens Files Using a ZPL Macro”, information is given on how to open the Monte Carlo files from a macro. In this article, we’ll go into greater detail on how to extract data from each of the files, and generate a summary report of the individual perturbations in each file.



Step 1: Performing the Monte Carlo Tolerance Analysis

Tolerance perturbations may be significantly different from one system to the next. Thus, it is difficult to develop a macro that can be used to extract Monte Carlo data from any general file. In this article, a macro has been developed which is suited to a particular system that is being analyzed. However, the general structure of the macro can be replicated and subsequently customized for most files of interest.

The first step in creating the macro is to determine what tolerance perturbations will be evaluated in the system. The example used for this article is a Cooke triplet (as given in the sample file <data>\Samples\Sequential\Objectives\Cooke 40 degree field.zmx). The default set of tolerances will be used in the analysis:

List of default tolerances for Monte Carlo analysis

Some minor changes to this default set are made, namely: 1) intermediate thickness compensation is turned off (Adjust = Surf for all of the TTHI operands) and 2) surface decenters are referenced to the back surface for each lens (all TSDX and TSDY operands are deleted for surfaces 2, 4, and 6). The resulting system may be found in the archive (.ZAR) file located at the end of this article.

There are 41 perturbations to be analyzed in this system:

• 6 radii of curvature
• 5 thicknesses (back focal length is used as a compensator)
• 3 element decenters in X
• 3 element decenters in Y
• 3 element tilts about X
• 3 element tilts about Y
• 3 surface decenters in X
• 3 surface decenters in Y
• 6 surface irregularities
• 3 refractive indices
• 3 Abbe numbers

corresponding to the 41 tolerance operands found in the Tolerance Data Editor. The macro we will write must therefore store data for these 41 perturbations for all of the Monte Carlo runs.

The Monte Carlo analysis is then performed. For this example, RMS spot radius is chosen as the tolerance criterion:

Tolerance criterion for Monte Carlo analysis

and 100 Monte Carlo runs are performed:

100 Monte Carlo runs are performed, all of which are saved

Remember that we must save each of the runs in order to extract the desired data. The name of the files will be “MC_Txxxx”, where xxxx corresponds to the run number.



Step 2: Creating the ZPL Macro

The macro used to extract data from the Monte Carlo runs for this specific example is provided on the last page of this article. The first step is to specify the number of runs that were performed:

! Define number of MC runs

n_files = 100

Data arrays are then defined to store the perturbation values for each run. Arrays are created to hold data for the 6 radii of curvature (trad1_per, …, trad6_per), the 5 thicknesses (tthi1_per, …, tthi5_per), etc. For surface irregularities – which in this example have been modeled using the TIRR operand – arrays are defined to store the magnitude of the irregularity (tirrm1_per, …, tirrm6_per) as well as the angle of  the astigmatism error (tirra1_per, …, tirra6_per). An array is also defined to hold the criterion value for each run (tcrit_per).

The nominal values for each of the perturbations (radii, thicknesses, etc.) are then obtained, using the TOLV function:

! Get nominal values for radii, thicknesses, indices, and Abbe numbers
! (all other perturbations have a nominal value of zero)

trad1_nom = TOLV(3,90)
trad2_nom = TOLV(4,90)
trad3_nom = TOLV(5,90)
trad4_nom = TOLV(6,90)
trad5_nom = TOLV(7,90)
trad6_nom = TOLV(8,90)

tthi1_nom = TOLV(9,90)
tthi2_nom = TOLV(10,90)
tthi3_nom = TOLV(11,90)
tthi4_nom = TOLV(12,90)
tthi5_nom = TOLV(13,90)

tind1_nom = TOLV(38,90)
tind3_nom = TOLV(39,90)
tind5_nom = TOLV(40,90)

tabb1_nom = TOLV(41,90)
tabb3_nom = TOLV(42,90)
tabb5_nom = TOLV(43,90)

As indicated in the macro comment, in this case the nominal values are all zero for the perturbations not listed (e.g. element tilts).

We are now ready to loop through all of the Monte Carlo files and extract the desired perturbation data. We first get the full file name for our nominal file, so that we may re-load this file at the end of our loop:

N$ = $FILEPATH()

We then define a string variable which will be the basis for the Monte Carlo file name (with full path included – we have assumed that all of the Monte Carlo files are in the same directory as the nominal file):

A$ = $PATHNAME()
B$ = A$+"\MC_T"

A FORMAT keyword is then used to specify the format in which the file number will be added to the file name, to be consistent with the Zemax file numbering system:

FORMAT "%#04i" LIT

This keyword will only work is the number of Monte Carlo files is < 10,000, which seems like a reasonable limit for the type of analysis we are performing. Finally, the FOR loop is started:

FOR i, 1, n_files, 1

Inside of the loop, we generate the string which will contain the full file name of the Monte Carlo file, and then load the file using the LOADLENS keyword:

       F$ = B$+$STR(i)+".zmx"
LOADLENS F$

Then the desired data are extracted from the file, using the MFCN function (for the tolerance criterion value), the RADI function (for the radii of curvature), the THIC function (for the thicknesses), the PARM function (for the surface and element decenters, element tilts, and surface irregularities), and the SOLV function (for the refractive indices and Abbe numbers). In the appropriate cases, the nominal values were subtracted from the obtained value, in order to calculate the perturbation value.

We see that the surface number inputs to the macro functions have been hard-wired into the code, and that in all cases the surface numbers differ from the numbers in the nominal file. This is because the Monte Carlo file will have additional surfaces relative to the nominal file, in order to model element tilts and decenters (via Coordinate Break surfaces). To determine the appropriate surface numbers in each case, one of the Monte Carlo files was manually opened and investigated.

Once the FOR loop is complete, we reload the nominal file. We then print the results to the screen, using another FOR loop, with FORMAT keywords also placed to control the numerical precision of the printed data:

! Print the results

PRINT "Run#   Criterion       ",
PRINT "RAD1       RAD2       RAD3       RAD4       RAD5       RAD6       ",
PRINT "THI1       THI2       THI3       THI4       THI5       ",
PRINT "TEDX12     TEDY12     TETX12     TETY12     ",
PRINT "TEDX34     TEDY34     TETX34     TETY34     ",
PRINT "TEDX56     TEDY56     TETX56     TETY56     ",
PRINT "TSDX1      TSDX3      TSDX5      TSDY1      TSDY3      TSDY5       ",
PRINT "TIRRM1          TIRRM2          TIRRM3          ",
PRINT "TIRRM4          TIRRM5          TIRRM6          ",
PRINT "TIRRA1     TIRRA2     TIRRA3     TIRRA4     TIRRA5     TIRRA6       ",
PRINT "TIND1      TIND3      TIND5      ",
PRINT "TABB1      TABB3      TABB5"
FOR i, 1, n_files, 1
FORMAT "%#04i" LIT
PRINT i, "   ",
FORMAT 10.5 EXP
PRINT tcrit_per(i), " ",
FORMAT 10.5
PRINT trad1_per(i), " ", trad2_per(i), " ", trad3_per(i), " ",
PRINT trad4_per(i), " ", trad5_per(i), " ", trad6_per(i), " ",
PRINT tthi1_per(i), " ", tthi2_per(i), " ", tthi3_per(i), " ",
PRINT tthi4_per(i), " ", tthi5_per(i), " ",
PRINT tedx12_per(i), " ", tedy12_per(i), " ",
PRINT tetx12_per(i), " ", tety12_per(i), " ",
PRINT tedx34_per(i), " ", tedy34_per(i), " ",
PRINT tetx34_per(i), " ", tety34_per(i), " ",
PRINT tedx56_per(i), " ", tedy56_per(i), " ",
PRINT tetx56_per(i), " ", tety56_per(i), " ",
PRINT tsdx1_per(i), " ", tsdx3_per(i), " ", tsdx5_per(i), " ",
PRINT tsdy1_per(i), " ", tsdy3_per(i), " ", tsdy5_per(i), "    ",
FORMAT "%+10.5e" LIT
PRINT tirrm1_per(i), "   ", tirrm2_per(i), "   ", tirrm3_per(i), "   ",
PRINT tirrm4_per(i), "   ", tirrm5_per(i), "   ", tirrm6_per(i), "   ",
FORMAT 10.5
PRINT tirra1_per(i), " ", tirra2_per(i), " ", tirra3_per(i), " ",
PRINT tirra4_per(i), " ", tirra5_per(i), " ", tirra6_per(i), " ",
PRINT tind1_per(i), " ", tind3_per(i), " ", tind5_per(i), " ",
PRINT tabb1_per(i), " ", tabb3_per(i), " ", tabb5_per(i), " "
NEXT i


Finally, the memory associated with each array is freed using the RELEASE keyword.

This macro is customized for the file provided in this example. However, the basic structure of the macro may remain the same even as the file and/or the tolerance perturbations differ.



Step 3: Running the Macro

Once the macro is complete, it can be run to generate the desired data:

Results from macro

This output may then be sent to a text file:

Saving the macro results to a file

for future analysis.



Summary
Generally, a designed is not interested in the individual perturbations generated in a Monte Carlo tolerance run. However, this information is available if all of the Monte Carlo files are saved. A ZPL macro can then be used to automate retrieval of the desired data.



Attachments





© All Rights Reserved.