Skip to main content

Hi All,

I’ve been trying to write a Python Interactive Extension with the ZOS-API. Having started with the boilerplate generated through the GUI at Programming > Python > Interactive Extension, I appended the following code at the end of the generated file:

# Insert Code Here

import typing

psfWindow = TheSystem.Analyses.New_HuygensPsf()

settings = typing.cast(psfWindow.GetSettings(),ZOSAPI.Analysis.Settings.Psf.IAS_HuygensPsf)

field = settings.Field

field = typing.cast(field, ZOSAPI.Analysis.Settings.IAS_Field)

print(str(field.GetFieldNumber()))

 

When I run this (having clicked on the Interactive Extension button as per the documentation), the following gets printed:

Found OpticStudio at:   %sc:\program files\zemax opticstudio                       Connected to OpticStudio                                                          Serial #:  L118546   

Traceback (most recent call last):                                                File "C:\Users\dshteinbok\Documents\Zemax\ZOS-API Projects\PythonZOSConnection1\PythonZOSConnection1.py", line 114, in <module>                                                                        print(str(field.GetFieldNumber()))                                              TypeError: not enough arguments

 

I am trying to access the method ZOSAPI.Analysis.Settings.IAS_Field.GetFieldNumber() which is detailed in the included documentation and shouldn’t take any arguments. To investigate, I replaced the last line in the python code I gave above (the one that is actually calling GetFieldNumber()) with a line to investigate its __str__ method:

print(field.GetFieldNumber)

I got the output:

Found OpticStudio at:   %sc:\program files\zemax opticstudio                      Connected to OpticStudio                                                          Serial #:  L118546                                                                <unbound method 'GetFieldNumber'>  

That last line, “unbound method” makes it seem as though the method isn’t working because the name of the function is not bound to anything. This makes me wonder: was casting field as I did the wrong thing to do? What would be the proper approach?

By the way, I tried omitting the line that casts field to type IAS_Field , but having done this I got the error: AttributeError: 'PropertyObject' object has no attribute 'GetFieldNumber' 

 

Am I using the API incorrectly? How would you go about doing this (just getting the field number used in the Huygens PSF function)?

Thanks,

Daniel

Hi Daniel,

 

Here’s how I would access the field number of a Huygens PSF analysis in a Python interactive extension:

# Open the Huygens PSF analysis
huygens_psf = TheSystem.Analyses.New_HuygensPsf()

# Get analysis settings
huygens_psf_settings = huygens_psf.GetSettings()

# Get field number
field_number = huygens_psf_settings.Field.GetFieldNumber()

# Print field number
print('Field number: ' + str(field_number))

# Close the analysis
huygens_psf.Close()

The result in a new filed looks like so:

Field number: 1

Hope this helps.

Take care,

 

David

 


Hi David,

Replacing my code with exactly what you wrote, I get:

Found OpticStudio at:   %sc:\program files\zemax opticstudio                                                                                                                                           Connected to OpticStudio                                                                                                                                                                               Serial #:  L118546                                                                                                                                                                                     Traceback (most recent call last):                                                                                                                                                                       File "C:\Users\dshteinbok\Documents\Zemax\ZOS-API Projects\PythonZOSConnection1\PythonZOSConnection1.py", line 124, in <module>                                                                          field_number = huygens_psf_settings.Field.GetFieldNumber()                                                                                                                                         AttributeError: 'IAS_' object has no attribute 'Field'     

This is a similar error to what I got when I “tried removing the line that casts field” in my post, but for the settings object rather than the field object.

I am using Python 3.10.4. Do you think that’s a possible culprit, or do you think it’s an OpticStudio/my code problem?

 

Thanks,

Daniel 


A further update:

I downgraded to python 3.8.13, and the issue persists exactly as before. It seems like it’s an issue of New_HuygensPsf() returning an instance of the base class IAS_ rather than IAS_HuygensPsf(). This is actually consistent with the documentation, but it’s strange that the consequent behavior differs from David’s expectation. Casting with typing.cast as in my original post solves this issue for the settings object but does NOT solve this issue for the object returned by huygens_psf_settings.Field. I provide a modification of David’s code to demonstrate:

First, casting huygens_psf_settings:

# Open the Huygens PSF analysis
huygens_psf = TheSystem.Analyses.New_HuygensPsf()

# Get analysis settings
huygens_psf_settings = huygens_psf.GetSettings()

# MY ADDITION: Cast huygens_psf_settings
import typing
huygens_psf_settings = typing.cast(huygens_psf_settings, ZOSAPI.Analysis.Settings.Psf.IAS_HuygensPsf)

# Get field number
field_number = huygens_psf_settings.Field.GetFieldNumber()

# Print field number
print('Field number: ' + str(field_number))

# Close the analysis
huygens_psf.Close()

This resolves the issue raised by David’s original code as per my previous reply, but produces a new error:

Found OpticStudio at:   %sc:\program files\zemax opticstudio                                                                                                                                           Connected to OpticStudio                                                                                                                                                                               Serial #:  L118546                                                                                                                                                                                     Traceback (most recent call last):                                                                                                                                                                       File "PythonZOSConnection1.py", line 126, in <module>                                                                                                                                                    field_number = huygens_psf_settings.Field.GetFieldNumber()                                                                                                                                         AttributeError: 'PropertyObject' object has no attribute 'GetFieldNumber'    

Here, we circle back to the original problem presented in my first post. huygens_psf_settings.Field does not return a type consistent with the documentation! I think this is a bug, and perhaps I should open an issue. Anyway, proceeding further to cast this result of huygens_psf_settings.Field to the type that should be returned according to the documentation leaves GetFieldNumber as an unbound method, and calling it raises an error of “incorrect number of arguments” because it has no implementation. This seems to me to be a problem with ZOS-API itself, but I may be wrong.

I am using Zemax OpticStudio 22.2.1 Professional (64 bit)


Hi Daniel,

 

Sorry, I should have said that my code works with OpticStudio 22.2.1,  Python 3.8.13, and Pythonnet 2.5.2. There have been some discussions recently about the more recent Pythonnet libraries, but I think the API doesn’t support it yet. Could you check your version of Pythonnet?

Take care,

 

David


Hi David,

 

Thank you very much for the response, you were right. I downgraded pythonnet to 2.5.2 and that resolved all issues. I was previously running pythonnet 3.0.0 which explains everything.

 

Thanks again for your time,

Daniel


Reply