Skip to main content
Solved

Universal 1-D Plot with NSD: ZOS-API in Python

  • January 27, 2025
  • 5 replies
  • 114 views

Matteo

Hi everybody,

I need your advice / help for using the API.
I am currently trying to run my Zemax file over the interactive mode with python. So far, I have managed with the help of the ZOS-API Syntax help and the examples presented there, but I am not getting any further at this point. 

The Zemax file I want to control is a non-sequential system.
I would like to create a Universal 1-D Plot where I plot the value of one operand (=NSDD) in my merit function in dependence of the tilt angle of an object in my system. In the image attached at the bottom you can see the settings I would like to set over python. 
I am struggling with setting the field “NSC Data” with python. In the documentation under KEYWORDS-->MODIFYSETTINGS I cannot find any setting for this option:

UN1_CATEGORY: Use 0 for surface, 1 for system, 2 for config.

 

I tried 3 for “NSC data” without success. You can find the python snippet I used below.
 

My question boiled down:

Is there a way to set the NSC category in an universal 1-D plot over python?
I workaround for me would be to open/load a predefined universal 1D plot with the correct settings. (I think that would be a .UPL file?)

Thanks in advance for any feedback or hint :)

Best,
Matteo
 

Python snippet:

print("Trying to create a universal 1-D plot with NSC data")

UnivPlot = TheSystem.Analyses.New_Analysis_SettingsFirst(constants.AnalysisIDM_UniversalPlot1D)
UnivPlot.Terminate()
UnivPlot.WaitForCompletion()
UnivPlot_Settings = UnivPlot.GetSettings()
UnivPlot_Set = CastTo(UnivPlot_Settings, "IAS_")  # Cast settings to IAS_ interface
print("Universal Plot has analysis specific settings? ", UnivPlot.HasAnalysisSpecificSettings)
# Above is False; Universal Plot Settings must be changed via ModifySettings (changing a config (.cfg) file)
cfg = TheApplication.ZemaxDataDir + "\\Configs\\UNI_MATTEO.CFG"
UnivPlot_Set.SaveTo(cfg)  # Create new .cfg file, named "UNI.CFG" in \Configs\ folder


UnivPlot_Set.ModifySettings(cfg, 'UN1_CATEGORY', 1)

# from KEYWORDS-> MODIFYSETTINGS: 
# UN1_CATEGORY: Use 0 for surface, 1 for system, 2 for config
# What is the category for NSC data??

UnivPlot_Set.ModifySettings(cfg, 'UN1_STARTVAL', -25)
UnivPlot_Set.ModifySettings(cfg, 'UN1_STOPVAL', 25)
UnivPlot_Set.ModifySettings(cfg, 'UN1_STEPS', 4)
UnivPlot_Set.ModifySettings(cfg, 'UN1_MFLINE', 3)
UnivPlot_Set.ModifySettings(cfg, 'UN1_PAR1', 1)
UnivPlot_Set.ModifySettings(cfg, 'UN1_PAR3', 3)
UnivPlot_Set.Save()

# Run the analysis with the new settings
UnivPlot_Set = CastTo(UnivPlot, 'IA_')
UnivPlot_Set.ApplyAndWaitForCompletion()

 

Is there a way to load a universal plot over python / API?

 

 

Target settings I would like to set over python

 

Best answer by David.Nguyen

@Matteo alas I did not manage to convince you 😝

If you didn’t find the setting in the Help File, then it is safe to assume it isn’t supported. Perhaps, you can make use of a similar approach to this:

You should be able to do the same in the ZOSAPI. The idea is to first set the settings of your 1-D Plot in the user interface, and then press the Save button. This will create a settings file (extension *.CFG) in the same folder as your lens file. Then, in your code, you can load that settings file with something like:

UnivPlot_Settings = UnivPlot.GetSettings()
UnivPlot_Settings.LoadFrom(path.CFG)
UnivPlot_Set.ApplyAndWaitForCompletion()

I haven’t tried it, but I think it should work.

Take care,

 

David

View original
Did this topic help you find an answer to your question?

5 replies

David.Nguyen
Luminary
Forum|alt.badge.img+2
  • Luminary
  • 1072 replies
  • January 27, 2025

@Matteo 

 

Unless you really like the old school graphics of the Universal Plot, why don’t you plot this data in Python directly? You will have much more freedom to adjust the plot to your liking.

import matplotlib.pyplot as plt
import numpy as np

start_value = -25.0
stop_value = 25.0
number_of_steps = 20

steps = np.linspace(start_value, stop_value, number_of_steps)

annular_volume = TheSystem.NCE.GetObjectAt(2)

mf_values = np.zeros(number_of_steps)

for ii, step in enumerate(steps):
    annular_volume.TiltAboutX = step

    TheSystem.MFE.CalculateMeritFunction()

    mf_values[ii] = TheSystem.MFE.GetOperandAt(3).Value

plt.figure()
plt.plot(steps, mf_values)
plt.xlabel('Tilt about X')
plt.ylabel('NSDD')
plt.show()

I don’t know if this makes sense, but its the result of the code above in an interactive extension with your file:

I hope this helps and take care,

 

David


Matteo
  • Author
  • Single Emitter
  • 2 replies
  • January 27, 2025

@David.Nguyen 

Hi David,

many thanks for your reply!
The attached file was just a simple example to illustrate my intention (and has no deeper meaning).
I also had the idea to directly plot the data in python. (In this case this would indeed be an option).

Let’s say I would really need this “oldschool” plot from Zemax or want to create a zmx file with python where this plot should be created when opening the file. Do you (or anyone else out there :) )  know if there is a way to create the plot in Zemax for this case?

King regards,
Matteo

 


David.Nguyen
Luminary
Forum|alt.badge.img+2
  • Luminary
  • 1072 replies
  • Answer
  • January 28, 2025

@Matteo alas I did not manage to convince you 😝

If you didn’t find the setting in the Help File, then it is safe to assume it isn’t supported. Perhaps, you can make use of a similar approach to this:

You should be able to do the same in the ZOSAPI. The idea is to first set the settings of your 1-D Plot in the user interface, and then press the Save button. This will create a settings file (extension *.CFG) in the same folder as your lens file. Then, in your code, you can load that settings file with something like:

UnivPlot_Settings = UnivPlot.GetSettings()
UnivPlot_Settings.LoadFrom(path.CFG)
UnivPlot_Set.ApplyAndWaitForCompletion()

I haven’t tried it, but I think it should work.

Take care,

 

David


Hi ​@Matteo and ​@David.Nguyen,

 

UnivPlot_Settings = UnivPlot.GetSettings()
UnivPlot_Settings.LoadFrom(path.CFG)
UnivPlot_Set.ApplyAndWaitForCompletion()

I haven’t tried it, but I think it should work.

 

Loading a settings file this was should indeed work (at least with other analyses). I am not sure if having the settings file in the same folder of your lens file always works. I usually resort to absolute file paths as that is the most robust in my experience. Something like

from pathlib import Path

fp = Path(r'customconfig.CFG').absolute().as_posix()
UnivPlot_Settings.LoadFrom(fp)

 

Luc


Matteo
  • Author
  • Single Emitter
  • 2 replies
  • February 6, 2025

Hi ​@David.Nguyen ,

thanks again for your reply. The idea to first set up the config and load in that one afterwards is really nice and helpful! It worked perfectly in the way you proposed.
Out of curiosity, I tried to modify the uploaded settings of the NSC-Config. Unfortunately, this is not possible. (But no problem for me 😊 ) 
 

Best, Matteo


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings