Python.NET 3.x is completely "Fixed"

  • 19 January 2024
  • 1 reply
  • 101 views

Userlevel 3
Badge

ZOSPy 1.2.0 has just been released, and brings a definitive fix to the Python.NET 3 problems.

How it works is explained in the documentation.

Explanation of abbreviations:

  • zp: abbreviation for ZOSPy
  • zos: ZOSPy class that manages the connection with the ZOS-API.
  • oss: ZOSPy's wrapper for optical systems, equivalent to TheSystem in the ZOS-API documentation.

 

ZOSPy connects to the ZOS-API using Python.NET. Python.NET converts .NET objects to Python objects and vice versa, and it allows to customize this conversion behaviour using codecs.

To solve the problems related to Python.NET 3, we use a custom encoder. This encoder automatically downcasts generic interfaces to specific implementations. The ZOS-API often defines a generic interface which is implemented by many other, more specific interfaces.

Example:

The ZOSAPI.Analysis.Settings.IAS_ interface specifies the properties and methods that should be implemented by the settings object of all analyses. Many analyses have settings that are specific to that analysis, and these settings are specified by a separate interface. For example, the Huygens PSF settings are specified by the ZOSAPI.Analysis.Settings.Psf.IAS_HuygensPsf interface, which also inherits from ZOSAPI.Analysis.Settings.IAS_.

 

Starting with Python.NET 3, this leads to problems when the API returns objects implementing the generic interface, but you need to access a method or property of the specific interface. The solution to this problem is "downcasting" the generic interface to the specific interface. Python.NET uses the __implementation__ attribute for this. More information can be found in this topic:

Example:

If you create a Huygens PSF analysis using the "raw" ZOS-API, you cannot access its analysis specific settings:

import zospy as zp

zos = zp.ZOS()
oss = zos.connect(mode="standalone")

huygens_psf = oss.Analyses.New_Analysis_SettingsFirst(zp.constants.Analysis.AnalysisIDM.HuygensPsf)
huygens_psf_settings = huygens_psf.GetSettings()

print(huygens_psf_settings.Normalize) # AttributeError: 'IAS_' object has no attribute 'Normalize'

By downcasting using the __implementation__ attribute, the Huygens PSF settings can be accessed:

print(huygens_psf_settings.__implementation__.Normalize) # False

NOTE: this This example does not work out of the box, because ZOSPy solves this problem. You need to modify ZOSPy's source code to get this example working.

 

Manually accessing __implementation__ is unintuitive, and decreases code readability. ZOSPy's encoder solves this problem by automatically casting from the interface to the implementation class.

Interfaces that are automatically downcast

Interfaces need to be registered before they will be converted by OpticStudioInterfaceEncoder.
These interfaces are downcast by default:

  • ZOSAPI.Analysis.Settings.IAS_
    •   Access via zp.analyses.new_analysis(<analysis type>).Settings
    • Interface for analysis settings. PLEASE NOTE: zospy.analyses already performed downcasting before codecs were implemented.
  • ZOSAPI.Editors.LDE.ISurface
    • oss.LDE.GetSurfaceAt(<index>).SurfaceData
    • Surface data, which provides access to surface-specific settings (e.g. tilts and decenters of a Coordinate Break)
  • ZOSAPI.Editors.LDE.ISurfaceApertureType
    • Access via oss.LDE.GetSurfaceAt(<index>).ApertureData.CurrentTypeSettings
    • Interface for surface aperture settings
  • ZOSAPI.Editors.LDE.ISurfaceScatteringType
    • Access via oss.LDE.GetSurfaceAt(<index>).ScatteringData.CurrentTypeSettings
    • Interface for surface scattering settings
  • ZOSAPI.Editors.NCE.IObject
    • oss.NCE.GetObjectAt(<index>).ObjectData
    • Object data, which provides access to object-specific settings
  • ZOSAPI.Tools.ISystemTool
    • oss.Tools.CurrentTool
    • Interface for tool settings

Interfaces that are not automatically downcast

The interfaces listed below provide "convenience properties" to access the specific interfaces.
They are therefore not handled by OpticStudioInterfaceEncoder. Consult the OpticStudio documentation for more information.

  • ZOSAPI.Editors.ISolveData
  • ZOSAPI.Editors.NCE.ISourceColorSettings
  • ZOSAPI.Editors.NCE.IObjectScatteringSettings
  • ZOSAPI.Editors.NCE.IVolumePhysicsModelSettings
  • ZOSAPI.Editors.NCE.IIndexModelSettings

Example:

The 'Pickup' solver, which implements the ZOSAPI.Editors.ISolveSurfacePickup interface, can be accessed in this way:

# ThicknessCell is only an example, you can use any cell that supports the Pickup solver
oss.LDE.GetSurfaceAt(<index>).ThicknessCell.GetSolveData()._S_SurfacePickup

Note that ZOSPy includes helper functions for solvers in zospy.solvers. The above is just for illustrative purposes, and it is recommended to use zospy.solvers instead.

 

Registering additional interfaces for automatic downcasting

You can register additional interfaces using zospy.api.codecs.OpticStudioInterfaceEncoder.register_interfaces. If you think you found an interface that should be converted by default, please file an issue or create a Pull Request.


1 reply

Userlevel 3

Thanks for your efforts @chaasjes! This makes life much more intuitive and therefore easy :)

 

Reply