Package: zospy
ZOSPyAboutWrapper around theAnsys Zemax OpticStudioAPI that provides a more pythonic and
intuitive way to interact with theZOS-APIthrough python using a .NET connection. It thereby allows you to do more
optics modelling with less coding.In addition to full access to all the OpticStudio fucntions through the ZOS-API, ZOSPy provides the following features:Wrapper functions for several OpticStudio analyses inzospy.analyses;Easy access to solvers inzospy.solvers;Easy access to all API constants inzospy.constants;Autocomplete for all ZOS-API endpoints and constants;Solves common problems related to Python.NET 3 and interaction with the ZOS-API.Waranty and liabilityThe code is provided as is, without any warranty. It is solely intended for research purposes. No warranty is given and
no rights can be derived from it, as is also stated in theMIT license.InstallingZOSPy is available on PyPipip install zospyDependenciesZOSPy officially supports Python 3.9 - 3.12. It may work with older Python versions, but support is not provided for
these versions.Python packagesPython for .NET3.0.3pandasNumPySemVer3.0.2SoftwareAnsys Zemax OpticStudioCompatibilityZOSPy is tested with the following versions of Python and Ansys Zemax OpticStudio:Zemax20.3.223.1.023.2.124.1.0Python 3.9⚠✔✔✔Python 3.10⚠✔✔✔Python 3.11⚠✔✔✔Python 3.12⚠✔✔: This version works without problems.
⚠: This version works, but the output of analyses can differ slightly from the used reference version (currentlyOpticStudio 23 R1.01).ReferencingWhen publishing results obtained with this package, please cite the paper in which the package was first used:van Vught L, Que I, Luyten GPM and Beenakker JWM.Effect of anatomical differences and intraocular lens design on Negative Dysphotopsia.JCRS: Sep 06, 2022.
[doi:10.1097/j.jcrs.0000000000001054] [JCRS]If a direct reference of the package is also required, reference it using the following DOI:ContributingPlease read ourcontribution guidelinesprior to opening a Pull Request.Basic usageInitiating connectionThe connection as extension to running software OpticStudio is initiated as:importzospyaszpzos=zp.ZOS()oss=zos.connect("extension")Make sure that the OpticStudio software is set up to be connected to as extension through the API. Alternatively, a
standalone OpticStudio application can be launched by changing the last line to:oss=zos.connect("standalone")Using solversSolvers for the Lens Data Editor are available throughzp.solvers. Every solver requires a surface as its first
parameter.Examplesimportzospy.solversassolverssurface=oss.LDE.GetSurfaceAt(2)solvers.position(surface.ThicknessCell,from_surface=1,length=10)Performing analysesImplemented analyses are available thoughzp.analyses. The available analyses are grouped in files that correspond to
the analysis groups in OpticStudio (e.g.zp.analyses.mtfandzp.analyses.wavefront). Every analysis requires the
OpticStudioSystemossas first parameter.Examplesfromzp.analyses.mtfimportfft_through_focus_mtfmtf=fft_through_focus_mtf(oss,sampling='64x64',deltafocus=0.1,oncomplete='Close')fromzp.analyses.reportsimportcardinal_pointscp=cardinal_points(oss,surf1=3,surf2=4,oncomplete='Release')A full description of the available function parameters is provided in the docstrings.ConstantsAfter initiating the connection, all api constants are available throughzp.constants(
e.g.zp.constants.Editors.LDE.SurfaceType). Note that these are only available afterzos.wakeup()has been called,
as explained underInitiating connection.Convenience functionsSome convenience functions are available throughzp.functions, e.g. to change a surface to a standard stuface:newsurf=oss.LDE.InsertNewSurfaceAt(0)zp.functions.lde.surface_change_type(newsurf,'Standard')Full exampleThis example creates a simple optical system consisting of a single lens.# Create a new, empty systemoss.new()# Set aperture and wavelengthoss.SystemData.Aperture.ApertureType=zp.constants.SystemData.ZemaxApertureType.FloatByStopSizeoss.SystemData.Wavelengths.GetWavelength(1).Wavelength=0.543# in μm# Set the object at infinitysurface_object=oss.LDE.GetSurfaceAt(0)surface_object.Thickness=float("inf")# Use a very small stop size, so the system is approximately paraxialsurface_stop=oss.LDE.GetSurfaceAt(1)surface_stop.SemiDiameter=0.1# Add a lens with n = 1.5lens_front=oss.LDE.InsertNewSurfaceAt(2)lens_front.Comment="lens front"lens_front.Radius=20lens_front.Thickness=1zp.solvers.material_model(lens_front.MaterialCell,refractive_index=1.5)lens_back=oss.LDE.InsertNewSurfaceAt(3)lens_back.Comment="lens back"lens_back.Radius=-20lens_back.Thickness=19.792# System is in focusLoggingSome basic logging is implemented through the
standardpython logging module(but still under development). The
following implementation examples assume thatimport logginghas been executed.To enable logging output from all ZOSPy and other modules using logging.basicConfig:logging.basicConfig(level=logging.DEBUG,format='%(asctime)s-%(name)s-%(levelname)s-%(message)s')To enable logging output from all ZOSPy and other modules using a root logger:fmt=logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')sh=logging.StreamHandler()sh.setFormatter(fmt)sh.setLevel(logging.DEBUG)logger=logging.getLogger()logger.addHandler(sh)To enable logging output from only ZOSPylogging.getLogger('zospy').addHandler(logging.StreamHandler())logging.getLogger('zospy').setLevel(logging.INFO)ContactFeel free to contact us for any inquiries:C. Haasjes (email)J.W.M. Beenakker (email)L. van Vught (email)