ZOS-API.NET: An Overview

An application programming interface (API) for OpticStudio enables connections to, and customization of, the application using the latest software technology.

Authored By Sanjay Gangadhara

Introduction

ZOS-API.NET provides a powerful means of communicating with and/or customizing OpticStudio. The API allows users to write applications built on either COM (C++) or .NET (C#) code. Through the API, applications may either communicate directly with opened instances of OpticStudio or run OpticStudio as a background process. A significant amount of functionality exists in the API, and will continue to be built upon with future releases of OpticStudio.

In this article, we will show how to initizalize the ZOS-API and will provide helpful tools and tips for building your own applications.

Getting started with ZOS-API.NET

There are two different methods to connect to OpticStudio via ZOS-API.NET: Your application is standalone and will start up its own copy of OpticStudio with which to interact (Standalone Mode), or OpticStudio is already running and will call your application (all other modes, which we will refer to as ‘Inherent’ Modes).The free Express edition of Microsoft Visual Studio 2017 is available here.

To create a new C# project using Visual Studio:

  1. Choose File...New...Project...
  2. Select Template...Visual C#...Console Application
  3. Change the Name, Location and Solution name to something appropriate for your Solution/Project

You should see something like this:

Visual Studio Setup 1

Click OK and after your Solution/Project are generated, you should see something like:

 Visual Studio Setup 2

Next, open the Properties for your project. Generally, you should always target 64-bit for your .NET application when using OpticStudio, unless there is a specific reason that you need to use 32-bit. OpticStudio runs as a 64-bit application, and there is the potential for a mismatch with older versions of OpticStudio if the extension runs as 32-bit. You should make sure that both the Release and Debug Configurations specify 64-bit. By default, Visual Studio will have this set for 32-bit.

In your solution Explorer, right-click on References and in the menu select Add Reference… Then, in the Reference Manager click Browse and navigate to OpticStudio’s installed directory. Click ZOSAPI.dll and <Ctl-Click> to add ZOSAPI_Interfaces.dll. Your screen should appear as follows. 

Visual Studio Setup 3

Select Add, and then press OK.  

Visual Studio Setup 4

Next, right-click on References, and in the menu select Add Reference….

Visual Studio Setup 5

In the Reference Manager select Browse and navigate to ZOS-API/Libraries. Then select ZOSAPI_NetHelper.dll, press Add, and then OK. Notice the ZOSAPI_NetHelper dll in the References Manager. 

Visual Studio Setup 8

In Solution Explorer...References right-click on ZOSAPI and select Properties from the menu. Change Copy Local to False. Repeat the same process for ZOSAPI_Interfaces. You do not change any Properties for ZOSAPI_NetHelper.

Visual Studio Setup 9

Boilerplate code

Useful built-in tools that automatically produce the boilerplate code are available in the ZOS-API.NET Application Builders section in the Programming tab of OpticStudio.

 ZOS-API.NET Application Builders

Note that boilerplate code templates have been provided for programming applications using C#, C++, MATLAB, and Python. For both C# and C++, templates are available for all communication modes.

C# Standalone Application

In MATLAB and Python, templates have been provided for Standalone Applications and Interactive Extensions.

 Python Interactive Extension

Note that when using Visual Studio Express to compile applications built with ZOS-API.NET, you will need to use the editions for Windows Desktop or for Community; other versions of Visual Studio Express will not be compatible with the API.

The code snippets below are the standard boilerplate code that every application built using ZOS-API.NET needs. These samples do not include complete error handling. It is strongly advised that you add your own style of error handling. Checking each return value against ‘null’ before using it is good practice. Similarly, wrapping code in try/catch blocks will help you handle untoward behavior. The variable names used here are intended to be ‘self-documenting’, but you are of course free to change them as desired.

Note: Main() initializes the system and then calls another function to actually ‘connect’ to the API and do the actual work for your application. Due to possible ‘order of operation optimizations’ imposed by the operating system and by the compiler optimization, it is possible that certain code sequences could ‘pre-load’ functions which “aren’t there yet”. Therefore, it is best practice to have ‘Main’ call a secondary function and have that secondary function directs all the ‘work’ for your application.

Note: While not strictly necessary, it is good practice to check your license status prior to running any application built for the API. If your license is not up-to-date, or another license error occurs while attempting to connect to OpticStudio, the likelihood of your application running correctly is minimized.

Standalone Mode boilerplate code

using System; using ZOSAPI;

namespace CSharpStandaloneApplication

{

    class Program

    {

        static void Main(string[] args)

        {

            bool isInitialized = ZOSAPI_NetHelper.ZOSAPI_Initializer.Initialize();

            if (isInitialized)

            {

                LogInfo("Found OpticStudio at: " + ZOSAPI_NetHelper.ZOSAPI_Initializer.GetZemaxDirectory());

            }

            else

            {

                HandleError("Failed to locate OpticStudio!");

                return;

            }

           

            BeginStandaloneApplication();

        }

 

        static void BeginStandaloneApplication()

        {

            ZOSAPI_Connection TheConnection = new ZOSAPI_Connection();

            IZOSAPI_Application TheApplication = TheConnection.CreateNewApplication();

            if (TheApplication == null)

                {

                HandleError("An unknown connection error occurred!");

                     return;

                }

            if (!TheApplication.IsValidLicenseForAPI)

            {

                HandleError("Failed to connect to OpticStudio: " + TheApplication.LicenseStatus);

                return;

            }

            if (TheApplication.Mode != ZOSAPI_Mode.Server)

            {

                HandleError("User plugin was started in the wrong mode: expected Server, found " + TheApplication.Mode.ToString());

                return;

            }

 

            IOpticalSystem TheSystem = TheApplication.PrimarySystem;

           

 

                FinishStandaloneApplication(TheApplication);

        }

           static void FinishStandaloneApplication(IZOSAPI_Application TheApplication)

           {

                if (TheApplication != null)

                {

                     TheApplication.CloseApplication();

                }

           }

 

        static void LogInfo(string message)

        {

            Console.WriteLine(message);

        }

 

        static void HandleError(string errorMessage)

        {

            throw new Exception(errorMessage);

        }

 

    }

}

Inherent modes boilerplate code

Below, you will find boilerplate code for when OpticStudio is already running and will call your application (refered to as ‘Inherent’ Modes). 

using System;

using ZOSAPI;

 

namespace CSharpUserExtensionApplication

{

    class Program

    {

        static void Main(string[] args)

        {

            bool isInitialized = ZOSAPI_NetHelper.ZOSAPI_Initializer.Initialize();

            if (isInitialized)

            {

                LogInfo("Found OpticStudio at: " + ZOSAPI_NetHelper.ZOSAPI_Initializer.GetZemaxDirectory());

            }

            else

            {

                HandleError("Failed to locate OpticStudio!");

                return;

            }

           

            BeginUserExtension();

        }

 

        static void BeginUserExtension()

        {

            ZOSAPI_Connection TheConnection = new ZOSAPI_Connection();

            IZOSAPI_Application TheApplication = null;

            try

            {

                TheApplication = TheConnection.ConnectToApplication();

            }

            catch (Exception ex)

            {

                HandleError(ex.Message);

                return;

            }

            if (TheApplication == null)

            {

                HandleError("An unknown connection error occurred!");

                return;

            }

            if (TheApplication.Mode != ZOSAPI_Mode.Plugin)

            {

                HandleError("User plugin was started in the wrong mode: expected Plugin, found " + TheApplication.Mode.ToString());

                return;

            }

               

            if (!TheApplication.IsValidLicenseForAPI)

            {

                HandleError("Failed to connect to OpticStudio: " + TheApplication.LicenseStatus);

                return;

            }

 

            TheApplication.ProgressPercent = 0;

            TheApplication.ProgressMessage = "Running Extension...";

 

            IOpticalSystem TheSystem = TheApplication.PrimarySystem;

                if (!TheApplication.TerminateRequested)

            {

           

 

            }

               

          

            FinishUserExtension(TheApplication);

        }

          

           static void FinishUserExtension(IZOSAPI_Application TheApplication)

           {

                if (TheApplication != null)

                {

                TheApplication.ProgressMessage = "Complete";

                TheApplication.ProgressPercent = 100;

                }

           }

 

        static void LogInfo(string message)

        {

            Console.WriteLine(message);

        }

 

        static void HandleError(string errorMessage)

        {

            throw new Exception(errorMessage);

        }

 

    }

}

Note that while applications built using Inherent Modes in C++ and C# compile to executable (.exe) files (just as with applications built using Standalone Mode), in order for Inherent Mode applications to be used by OpticStudio the .exe files need to be copied (or built) into OpticStudio's program folders:

  • Applications built in User Extensions Mode need to be placed in the Zemax\ZOS-API\Extensions folder
  • Applications built in User Operands Mode need to be placed in the Zemax\ZOS-API\Operands folder
  • Applications built in User Analysis Mode need to be placed in the Zemax\ZOS-API\User Analysis folder

Applications placed in the Zemax\ZOS-API\Extensions folder or the Zemax\ZOS-API\User Analysis folder will appear under the corresponding lists in Programming...ZOS-API Applications.

  User Analyses and User Extensions

Functionality available through ZOS-API.NET

Many of the details provided in the previous two sections of this article (Getting Started with ZOS-API.NET and Boilerplate Code) were taken from the full documentation for ZOS-API.NET, which may be found in the section entitled “About the ZOS-API” in the OpticStudio Help Files. This content may be accessed by selecting the ZOS-API Help icon in Programming...ZOS-API Applications.

  ZOS-API.NET Help Introduction

We strongly recommend reading the full documentation in the Help File prior to developing applications for the API. Note that specific documentation on the interfaces used by the API and a number of useful sample codes in C++, C#, Python, and Matlab may be found in the Syntax Help documentation.

Below we provide a general summary  of the functionality currently available in ZOS-API.NET.

System Explorer

  • The values of all items can be obtained and modified in all program modes

Editors (Lens Data, Non-Sequential Component, Multi-Configuration, Merit Function, Tolerance Data)

  • The values in all cells can be obtained and modified in all program modes
    • Note that in all cases cells are referenced by column number and not column header
  • The values of all data in the properties dialogs can be obtained and modified in all program modes

Analyses

For the following analyses, settings can be defined directly through the API and results may be retrieved directly into arrays of data:

  • Detector Viewer
  • Field Curvature and Distortion
  • Longitudinal Aberration
  • Lateral Color
  • Chromatic Focal Shift
  • Wavefront Map
  • Interferogram
  •  Foucault Analysis
  •  FFT PSF
  •  FFT PSF Cross-Section
  • FFT Line/Edge Spread
  •  Huygens PSF
  • Huygens PSF Cross-Section
  • FFT MTF
  • FFT Through Focus MTF
  • FFT Surface MTF
  • FFT MTF vs. Field
  • FFT MTF Map
  • Huygens MTF
  • Huygens Through Focus MTF
  • Huygens Surface MTF
  • Huygens MTF vs. Field
  • Geometric MTF
  • Geometric Through Focus MTF
  • Geometric MTF vs. Field
  • Geometric MTF Map
  • RMS vs. Field
  • RMS vs. Wavelength
  • RMS vs. Focus
  • RMS Field Map
  • Diffraction Enclosed Energy
  • Geometric Enclosed Energy
  • Geometric Line/Edge Spread
  • Extended Source Enclosed Energy
  • Surface Sag
  • Surface Phase
  • Surface Curvature
  • Surface Sag Cross-Section
  • Surface Phase Cross-Section
  • Surface Curvature Cross-Section
  • Full-Field Aberration
  • Contrast Loss Map
  • Grin Profile

For the above analyses, the resulting output data may be based on data in the current database (e.g. as saved as a part of the session file if reading data from an opened file), or by modifying the settings for the analysis and then getting the results. Results include the calculated values themselves, as well as any text/header data that would appear if viewing the analysis in the user interface.

For the following analyses, settings can be defined directly through the API and results may be retrieved using the GetTextFile method:

  • Single Ray Trace
  • Ray Fan
  • Standard Spot Diagram
  • Footprint Diagram
  • Through Focus Spot Diagram
  • Full Field Spot Diagram
  • Matrix Spot Diagram
  • Configuration Matrix Spot Diagram
  • OPD Fan
  • Pupil Aberration Fan
  • Grid Distortion
  • Seidel Coefficients
  • Seidel Diagram
  • Zernike Fringe Coefficients
  • Zernike Standard Coefficients
  • Zernike Annular Coefficients
  • Zernike Coefficients vs. Field

For all other analyses, settings may be defined using the ModifySettings method and results may be retrieved using the GetTextFile method.

Tools

The following tools are supported (the tool location is provided in parentheses):

  • Add Coatings to All Surfaces (Lens Data Editor)
  • Convert Global To Local Coordinates (Lens Data Editor)
  • Convert Local To Global Coordinates (Lens Data Editor)
  • Convert Semi Diameters to Circular (Lens Data Editor)
  • Convert Semi Diameters to Floating (Lens Data Editor)
  • Convert Semi Diameters to Maximum (Lens Data Editor)
  • Remove All Apertures (Lens Data Editor)
  • Replace Vignetting with Apertures (Lens Data Editor)
  • Reload Object (Non-Sequential Component Editor)
  • Reload All Objects (Non-Sequential Component Editor)
  • Delete Configuration (Multi-Configuration Editor)
  • Insert Configuration (Multi-Configuration Editor)
  • Next Configuration (Multi-Configuration Editor)
  • Previous Configuration (Multi-Configuration Editor)
  • Insert Configuration with Pickups (Multi-Configuration Editor)
  • Make Single Configuration (Multi-Configuration Editor)
  • Insert Merit Function (Merit Function Editor)
  • Load Merit Function (Merit Function Editor)
  • Save Merit Function (Merit Function Editor)
  • Delete All Operands (Merit Function Editor)
  • Default Merit Function Wizard (Merit Function Editor)
  • Create Archive (File Tab)
  • Load Archive (File Tab)
  • Export CAD (File Tab)
  • Non-Sequential Ray Trace (Analyze Tab – Non-Sequential UI mode)
  • LightningTrace (Analyze Tab – Non-Sequential UI mode)
  • Remove All Variables (Optimize Tab)
  • Set All Radii Variable (Optimize Tab)
  • Set All Thickness Variable (Optimize Tab)
  • Quick Adjust (Optimize Tab)
  • Quick Focus (Optimize Tab)
  • Local Optimization (Optimize Tab)
  • Hammer Optimization (Optimize Tab)
  • Global Optimization (Optimize Tab)
  • Ray Trace of custom rays (not directly in UI; previously supported with DDE)

All DDE data items are supported by ZOS-API.NET, with the following exceptions:

  • CloseUDOData
  • ReleaseWindow
  • SetUDOData
  • ExportCheck
  • GetAddress
  • GetAspect
  • GetMetaFile
  • GetRefresh
  • GetSequence
  • GetSettingsData
  • GetUDOSystem
  • PushLens
  • PushLensPermission
  • SetSettingsData
  • WindowMaximize
  • WindowMinimize
  • WindowRestore

Project Preferences

The following data values in the Project Preferences dialog can be obtained and modified:

  • DateTimeType
  • EncodingType
  • LanguageType
  • ShowLineAsType

Finally, note that Undo/Redo functionality is not currently supported in the ZOS-API.

KA-01517

Was this article helpful?
1 out of 3 found this helpful

Comments

0 comments

Please sign in to leave a comment.