Skip to main content

Hi!



Is there a way to run a macro from ZOS-API?



I have a macro that does some calculation on the currently opened Zemax model and outputs some data. In a Python script I want to make some modifications to the Zemax model using the ZOS-API and then run my macro. Is that possible?



Best,



Erik

Hi Erik,



I'm explaining a glitchy technique to do just that in this post.



The idea is to setup a ZPL Macro Solve in ZOS-API. Doing so will get the macro to execute. Don't forget it needs to have a SOLVERETURN keyword, and be sure to double-check how the macro executes. I have found that through this technique it sometimes has unexpected behavior.



Hope this helps.



Take care,



David


Hi David,



thank you for your answer. Using macro solve sounds like a clever trick, but also a bit of a hack. I would rather need something that runs the macro reliably once, since execution of my macro takes roughly an hour.



I gather from your other post, that there is no built-in clean way to execute a macro from ZOS-API, right?



Best,



Erik


Hi Erik,



Its definitely on the hacky side. To the best of my knowledge (and others can correct me), it is not possible to run a macro directly from within the ZOS-API. I guess the rationale behind this choice is that everything you can do in a macro, you can also do in the ZOS-API.



Apart from the work of translating your macro to the ZOS-API, is there something that prevents you from doing everything from the ZOS-API?



Take care,



David


Hi David,



it's mostly that I didn't want to do the double work of translating ZPL to Python. But I might just go down that road.



Best,



Erik


Hi Erik,



I understand you. This is probably what I would do as well.



Good luck with that, and let the community know if you need help.



Take care,



David


Hello David,

I have a problem to open the link you sent. Maybe you could sent a photo of it or something.

From my side, my problem is just to run a Zemax macro via python.

Thank you,

David


Hi David,

 

I can’t seem to be able to edit my post. The link got broken after they updated the forums.

This is the post I was referring to:

Also, I did not get notified of your reply, fortunately I was browsing the forum and saw it :p

Take care,


David


Thank you David, that is really helpful!

Best regards,

David.


Hello again David,

I have 2 other questions:

How would you run a very simple Zemax macro (generating the tolerance analysis in a text file) from python?

The macro works really well, but to make it more useful, I need to execute it on python, in order to run it several times.

I could have done everything in python (using tolerancing syntax of ZOS-API) but I am not very familiar with the ZOS-API syntax, and the tutorial link Getting Started with the ZOS-API which you suggested in the post is broken. That where comes my second question: could you send me the tutorial link if it still exist?

Thank you very much,

David


Hi David,

 

I’m not sure I understand your first question, because I thought this is what I described in the link I gave you above. Let me rephrase what I would do, and you tell me if this answers your question.

If I absolutely had to run a ZPL macro from Python, I would do as described in my previous post, that is:

  1. Creating a Python Standalone Application from a template (Programming..Python..Standalone Application)
  2. Insert a dummy surface in the lens file
  3. Place a macro solve on the radius of the dummy surface, for example

In order to do that, you need to modify your original macro, such that it has a SOLVERETURN keyword, this is a requirement for a solve. But it can return anything, you can simply have SOLVERETURN 0, and the rest of your macro still runs normally. Although, remember, this technique is glitchy, and I’m not sure it can run all the tools (you need to verify it yourself).

The code to do that can be found on my github repository, but I’ll copy the relevant lines for you here:

    # Create a definition for the Macro Solve type

    MacroSolveDef = ZOSAPI.Editors.SolveType.ZPLMacro

    

    # Add a dummy surface at the end of the LDE

    DummySurface = TheLDE.AddSurface()

    

    # Create a Macro Solve on the radius of the dummy surface

    MacroSolve = DummySurface.RadiusCell.CreateSolveType(MacroSolveDef)

    

    # Select the macro to be run (this dummy macro writes a text file in the

    # same directory as the lens file and is attached to the repository)

    MacroSolve.Macro = 'Standalone_text_example'

    

    # Apply the macro solve

    DummySurface.RadiusCell.SetSolveData(MacroSolve)

To answer your second question, these were called learning paths, but I wasn’t able to find them anymore. The only thing I found is the list of ZOS-API related knowledgebase articles here, which is probably a good place to start. Also, if you share your macro here, I can help you get started, and point you to relevant articles.

I hope that makes sense.

Take care,

 

David


Hi @David.RODIN that tutorial for “Getting Started with ZOS-API” is found here:

Free Tutorials – Zemax


Hello David and Alissa,

Thanks a lot for your answers!

@David.Nguyen I am trying to execute the programs the way you told me but I am not sure I am doing it the right way. I replaced the ‘standalone_text_example’ by the name of my Macro: ‘Tolerancing.ZPL’. I don’t know if it is the good syntax to use or not.

I will  show you here my Macro code and my Python code so you can understand me better:

 

Macro code:

TOLERANCE test.TOL, RESULTtoto.txt
SOLVERETURN 0

 

Python code (in the ‘insert code’ part of the standard python standalone application):

   MacroSolveDef = ZOSAPI.Editors.SolveType.ZPLMacro

    

    # Add a dummy surface at the end of the LDE

    DummySurface = TheLDE.AddSurface()

    

    # Create a Macro Solve on the radius of the dummy surface

    MacroSolve = DummySurface.RadiusCell.CreateSolveType(MacroSolveDef)
    

    # Select the macro to be run (this dummy macro writes a text file in the

    # same directory as the lens file and is attached to the repository)

    MacroSolve.Macro = 'Tolerancing.ZPL'

    

    # Apply the macro solve

    DummySurface.RadiusCell.SetSolveData(MacroSolve)

 

Have a nice day.

 

Best regards,

 

David

 

 


Hi David,

 

Running the tolerancing from a macro solve makes my OpticStudio crash. It is why I recommend testing the behaviour before trying this glitch. I guess the tolerancing tool is not meant to be used through a macro solve.

However, the tolerancing tool can be used directly through the ZOS-API, almost without problem (more about that at the end of my post).

Once at the “Insert Code” part, you can open, and close the tolerance tool as follow:

TheToleranceTool = TheSystem.Tools.OpenTolerancing()

# Tolerance tool manipulation goes here!

TheToleranceTool.Close()

Remember, only a single tool can be open at any one time. It is essential that you close it before opening another one or it will cause an error.

The tool can be run with the method RunAndWaitForCompletion() as follow:

TheToleranceTool = TheSystem.Tools.OpenTolerancing()

TheToleranceTool.RunAndWaitForCompletion()

TheToleranceTool.Close()

You can edit the parameters of the tolerancing before the run, the list of available parameters can be found in the ZOS-API Syntax Help if you search for ITolerancing and click the first link (ZOSAPI>Tools>Tolerancing>ITolerancing). For example, you can specify the Output File as follow:

TheToleranceTool = TheSystem.Tools.OpenTolerancing()

TheToleranceTool.OutputFile = "RESULTtoto.txt"

TheToleranceTool.RunAndWaitForCompletion()

TheToleranceTool.Close()

There is also a method Load() to load a configuration file for the tolerancing (similar to your macro), but somehow I couldn’t get it to work for me (I might log a support request about it). However, this doesn’t have to be a problem since you can access all the configuration parameters from the ZOS-API.

Let me know if this makes sense, and if you need further help with this problem.

Take care,

 

David


Hello David,

 

Thank you, I understand better the ZOZ API syntax now. You are right, the macro might not be the optimal solution.

But yes I have another question: how can I specify which file I want to apply the tolerancing on?

Do I have to define local variables in order to load the correct file, or is there a specific tolerancing tool which already do it?

I have seen: TheSystem.LoadFile(), and in the tolerance tool Load() but I don’t really know which one to use. 

Best regards,

 

David.


Hi David,

one more thing you can try instead of using the ZOS-API is running a macro directly from the command line. That might be easier in some cases. The Zemax help has a section on “Running Macros from the Command Line”, which explains the call structure. In Python you can use the subprocess library to run that command. I didn’t test it myself, but it could look like this:

import subprocess
subprocess.run(s"rPATH_TO_OPTICSTUDIO.EXE]", '-zpl="-FULL_PATH_TO_ZPL_FILE]"', '-v'ARG_NAME_1]="Evalue]"'])

Best,

Erik


Hello Erik,

Thank you for this advice, I will try it myself.

Best regards,

David.


Hi David,

 

When you call the tolerancing tool from TheSystem it is calling the tool on the Primary System. If you call TheSystem.LoadFile() before, it will open the tolerancing tool for the system that’s just been loaded.

Let me know if this makes sense.

Take care,

 

David


Hello David,

Thank you, I understand.

I will tell you if I have any problems after it.

Best regards,

David.


Hi David,

 

Glad to hear. I got more information about the limitations I mentioned previously (I ended up reporting the faulty behaviour of the Load() method).

When you use the Load() method of the tolerance tool, there’s a known bug and you actually need to specify the full path to the *.TOP file, not just the file name.

If you wanted  to translate your original macro, the ZOS-API lines become:

TheToleranceTool = TheSystem.Tools.OpenTolerancing()

TheToleranceTool.Load(‘C:\...\Zemax\Configs\test.TOP’)

TheToleranceTool.OutputFile = "RESULTtoto.txt"

TheToleranceTool.RunAndWaitForCompletion()

TheToleranceTool.Close()

And you should replace the  with the path to your Documents folder. Also, I noticed in your macro the settings file is test.TOL I think it should be a *.TOP file. The *.TOL file is the actual tolerance editor data.

Let me know if this makes sense, and take care,

 

David


Hello David,

 

Actually I used your previous advice for generating the tolerancing via python ZOS-API, and now it work perfectly well!

I thought that using Zemax Macros would be a gain of time because the ZOS API syntax is new for me, but finally it work very well like this.

So thank you for your help, and you last advice about the Macro. :relaxed:

 

Have a nice day, and take care.

 

David.


Hi David,

 

I’m glad to hear you got it to work.

It is true that the ZOS-API syntax has a steeper learning curve, but ultimately it gives you this freedom to perform complex analysis.

Nice day to you too, and take care,

 

David


Reply