Single Ray Trace in the ZOS-API


In the last few weeks, I have received questions regarding how we can use the ZOS-API to pull single ray trace information. For convenience, I will post my answers here in a single post. I pulled together three different methods for extracting single ray trace data. Below I will list the methods with sample code in Python and Mathematica. I’m happy to provide samples in other languages if needed!
If you have other methods you use for this kind of analysis, feel free to add them as a reply!
Method 1 - Use the Single Ray Trace analysis
This method can be used to pull the results of the Single Ray Trace analysis window.
The benefit of this method is that the results are pulled for all surfaces at once. The drawback of this method is that the data is provided in text form. The output is a TXT file which must be parsed back into the program you are using. This is discussed in a bit more detail here: How to set RayInfo.Vignetted in ZOS-API_Python
Python
# Define the constants across all methods hx = 0.0 hy = 1.0 px = 0.0 py = 0.0 wave = 2 surf = TheSystem.LDE.NumberOfSurfaces # Method 1: Single Ray Trace analysis window # Open the analysis singleTrace = TheSystem.Analyses.New_Analysis(ZOSAPI.Analysis.AnalysisIDM.RayTrace) # Access the settings traceSettings = singleTrace.GetSettings() traceSettings.Hx = hx traceSettings.Hy = hy traceSettings.Px = px traceSettings.Py = py traceSettings.Wavelength.SetWavelengthNumber(wave) # Apply the settings singleTrace.ApplyAndWaitForCompletion(); # Pull the results results = singleTrace.GetResults() # This analysis does not have a native matrix or array built in so we must pull the text file results.GetTextFile(r'C:\...\singleRay.txt')
Mathematica
(*Define the constants across all methods*) hx = 0.0; hy = 1.0; px = 0.0; py = 0.0; wave = 2; surf = theSystem@LDE@NumberOfSurfaces; (*Open the analysis*) LoadNETType["ZOSAPI.Analysis.AnalysisIDM"]; singleTrace = theSystem@Analyses@NewUAnalysis[AnalysisIDM`RayTrace]; (*Access and change the settings*) traceSettings = singleTrace@GetSettings[]; traceSettings@Hx = hx; traceSettings@Hy = hy; traceSettings@Px = px; traceSettings@Py = py; traceSettings@Wavelength@SetWavelengthNumber[wave]; (*Apply the settings and run the analysis*) singleTrace@ApplyAndWaitForCompletion[]; (*Extract the results to a text file. This is required as there is no DataGrid or DataSeries method for the IAS_RayTrace interface*) results = singleTrace@GetResults[]; results@GetTextFile["C:\\...\\results.txt"];
Method 2 - Use optimization operands
This method can be used to pull the values of particular ray trace operands. This is advantageous if you are interested in a single value, such as the Y-intercept of a ray at a particular surface for a given ray. This is disadvantageous if you are interested in the full ray trace results (X, Y, Z, l, m, n, etc).
In this example, we will pull the Y-intercept data for the final surface in the system using the REAY operand. The inputs will match what we see here:
Extracting the operand values will not affect the Merit Function. This is equivalent to the OPEV numeric function in ZPL.
Python
########### Define the constants across all methods hx = 0.0 hy = 1.0 px = 0.0 py = 0.0 wave = 2 surf = TheSystem.LDE.NumberOfSurfaces # Access the Merit Function Editor interface TheMFE = TheSystem.MFE # Pull the operand value. This will pull the value without affecting the Merit Function opVal = TheMFE.GetOperandValue(ZOSAPI.Editors.MFE.MeritOperandType.REAY, surf, wave, hx, hy, px, py, 0, 0) # Print this value. This is the Y-value for a single surface and ray. Will need to loop for more print(opVal)
Mathematica
(*This method requests the values of optimization operands without including them in the Merit Function.Similar to OPEV within the ZPL.Useful for a small handful of operands or for a loop*) (*Step 1:Access the Merit Function Editor object and declare the required enumerations for this call*) theMFE = theSystem@MFE; LoadNETType["ZOSAPI.Editors.MFE.MeritOperandType"]; (*Step 2:Define the inputs. We are after REAY so the inputs are as follows...*) hx = 0.0; hy = 1.0; px = 0.0; py = 0.0; wave = 2; surf = theSystem@LDE@NumberOfSurfaces; (*Step 3:Get the value*) opVal = theMFE@GetOperandValue[MeritOperandType`REAY, surfNum, wave, hx, hy, px, py, 0, 0]
Method 3 - Run a single ray trace through the Batch Ray Trace tool
This method will pull a full set of ray data into your program of choice as native double or integer values, similar to the full Batch Ray Trace. This is particularly useful if you are extracting data into an array or matrix, as you will not need to parse any external files. This method will also report errors and vignetting as part of the ray trace. The downside of this method is that the data is pulled for a single surface. In other words, the rays are traced from the Object to the input surface.
This method makes use of “out double” values. Each language handles these a bit differently. You can read more about how to identify these in this post: What is an "out double" value in the ZOS-API?.
Note: The Batch Ray Trace interface is categorized as a tool. Only one tool-type item may be open at a time.
Python
########### Import modules to read the data from System import Enum, Int32, Double ########### Define the constants across all methods hx = 0.0 hy = 1.0 px = 0.0 py = 0.0 wave = 2 surf = TheSystem.LDE.NumberOfSurfaces ########### Method 3: Run a single ray trace through the Batch tool # Open the tool raytrace = TheSystem.Tools.OpenBatchRayTrace() # Run a single unpolarized ray trace with real rays # This tool accepts inputs and provides OUT-variable outputs # We must pre-define the output variables sysInt = Int32(1) sysDbl = Double(1.0) # Now run for a single ray output = raytrace.SingleRayNormUnpol(ZOSAPI.Tools.RayTrace.RaysType.Real, surf, wave, hx, hy, px, py, False, sysInt, sysInt, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl) # The values for the OUT variables are then stored in an array of name output # The value for Y is 4 when we index at 0 print(output[4]) # Close the tool. This is HUGELY important. In the API, only one Tool-type object may be open at a time raytrace.Close()
Mathematica
(*Single ray trace method.Best method for reading one ray at a time and extracting its data*) (*For this,we could use the Single Ray Trace analysis,or the Batch Ray Trace tool.The Batch Ray Trace is ideal here because the results will be extracted as native double/int/etc values in Mathematica*) (*Step 1:Open the tool*) raytrace = theSystem@Tools@OpenBatchRayTrace[]; LoadNETType["ZOSAPI.Tools.RayTrace.RaysType"]; LoadNETType["ZOSAPI.Tools.RayTrace.OPDMode"]; (*Step 2:Define our inputs*) hx = 0.0; hy = 1.0; px = 0.0; py = 0.0; wave = 2; surf = theSystem@LDE@NumberOfSurfaces; calcOPD = False; (*Step 3:Call the single ray trace and retrieve the OUT variables*) raytrace@SingleRayNormUnpol[RaysType`Real, surfNum, wave, hx, hy, px, py, calcOPD, errCode, vigCode, x, y, z, l, m, n, l2, m2, n2, opdVal, intensity]; raytrace@RunAndWaitForCompletion[]; (*Step 4:Check if the ray traced successfully.If so,read the data*) If[((errCode == 0) && (vigCode == 0)), Print["X = ", x]; Print["Y = ", y]] (*Step 5: Close the tool. This is REQUIRED as only one "tool" can be opened at a time*) raytrace@Close[];
Comments
-
I’ve received a few requests to provide the Matlab code for Method 3. It is here:
% Define the constants hx = 0.0; hy = 1.0; px = 0.0; py = 0.0; wave = 2; surf = TheSystem.LDE.NumberOfSurfaces - 1; % Method 3: Run a single ray trace through the Batch tool % Open the tool raytrace = TheSystem.Tools.OpenBatchRayTrace(); % Run a single unpolarized ray trace with real rays % This tool accepts inputs and provides OUT-variable outputs [success, error, vignette, xo, yo, zo, lo, mo, no, l20, m20, n20, opd, intensity] = raytrace.SingleRayNormUnpol(ZOSAPI.Tools.RayTrace.RaysType.Real, surf, wave, hx, hy, px, py, false); % The output is stored in the pre-defined variables above. Print one disp(yo); % Close the tool. This is HUGELY important. In the API, only one Tool-type object may be open at a time raytrace.Close()
0