Skip to main content

ZOS-API interface 2025 R1

Example 15 - C#

Last update: 17.07.2025

C#

using System;
using System.Diagnostics;
using System.Threading;
using ZOSAPI;
namespace CSharpStandaloneApplication
{
class Program
{
static void Main(string[] args)
{
// Find the installed version of OpticStudio
bool isInitialized = ZOSAPI_NetHelper.ZOSAPI_Initializer.Initialize();
// Note -- uncomment the following line to use a custom initialization path
//bool isInitialized = ZOSAPI_NetHelper.ZOSAPI_Initializer.Initialize(@"C:\Program Files\OpticStudio\");
if (isInitialized)
{
LogInfo("Found OpticStudio at: " + ZOSAPI_NetHelper.ZOSAPI_Initializer.GetZemaxDirectory());
}
else
{
HandleError("Failed to locate OpticStudio!");
return;
}
BeginStandaloneApplication();
}
static void BeginStandaloneApplication()
{
// Create the initial connection class
ZOSAPI_Connection TheConnection = new ZOSAPI_Connection();
// Attempt to create a Standalone connection
IZOSAPI_Application TheApplication = TheConnection.CreateNewApplication();
if (TheApplication == null)
{
HandleError("An unknown connection error occurred!");
return;
}
// Check the connection status
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;
bool b_load;
// creates new directory
string strPath = System.IO.Path.Combine(TheApplication.SamplesDir, @"API\CS\e15_Seq_Optimization");
System.IO.Directory.CreateDirectory(strPath);
// Load a double gauss design sample file
b_load = TheSystem.LoadFile(System.IO.Path.Combine(TheApplication.SamplesDir, @"Short course\Optical System Design Using OpticStudio\sc_dbga1.zos"), false);
Console.WriteLine("\n" + "Double Gauss Design:\n");
//Define path locations
string SamplesFolder = TheApplication.SamplesDir;
string SampleFile = System.IO.Path.Combine(TheApplication.SamplesDir, @"API\CS\e15_Seq_Optimization\OptimizedFile.zos");
TheSystem.SaveAs(SampleFile);
//Define System Explorer
//Define Aperture
ISystemData SystExplorer = TheSystem.SystemData;
SystExplorer.Aperture.ApertureType = ZOSAPI.SystemData.ZemaxApertureType.EntrancePupilDiameter;
SystExplorer.Aperture.ApertureValue = 20;
//Add 3 fields
IField Field_1 = SystExplorer.Fields.GetField(1);
IField NewField_2 = SystExplorer.Fields.AddField(0, 5.0, 1.0);
SystExplorer.Fields.SetFieldType(ZOSAPI.SystemData.FieldType.ParaxialImageHeight);
SystExplorer.Fields.MakeEqualAreaFields(3, 21.6);
//Add 3 wavelengths: F,d,C
bool slPreset = SystExplorer.Wavelengths.SelectWavelengthPreset(ZOSAPI.SystemData.WavelengthPreset.FdC_Visible);
//Open a shaded model
IA_ analysis = TheSystem.Analyses.New_Analysis(AnalysisIDM.ShadedModel);
analysis.Terminate();
analysis.WaitForCompletion();
IAS_ analysisSettings = analysis.GetSettings();
string cfgFile = System.IO.Path.GetTempFileName();
// Save the current settings to the temp file
analysisSettings.SaveTo(cfgFile);
// make your modifications to it
//MODIFYSETTINGS are defined in the ZPL help files: The Programming Tab > About the ZPL > Keywords
analysisSettings.ModifySettings(cfgFile, "SHA_ROTX", "90");
analysisSettings.ModifySettings(cfgFile, "SHA_ROTY", "0");
analysisSettings.ModifySettings(cfgFile, "SHA_ROTZ", "0");
// now load in the modified settings
analysisSettings.LoadFrom(cfgFile);
// If you want to overwrite your default CFG, copy it after you are done modifying the settings:
//string CFG_fullname = System.Environment.GetEnvironmentVariable("USERPROFILE") + "\\Documents\\Zemax\\Configs\\Configs\\POP.CFG";
//System.IO.File.Copy(cfgFile, CFG_fullname, true);
// We don't need the temp file any more, so delete it
System.IO.File.Delete(cfgFile);
// Run the analysis with the new settings
// remove all variables and add a F# solve on last surface radius
ILensDataEditor TheLDE = TheSystem.LDE;
IOpticalSystemTools tools = TheSystem.Tools;
ILDERow Surface_Last = TheLDE.GetSurfaceAt(TheLDE.NumberOfSurfaces - 2);
ISolveData Solver = Surface_Last.RadiusCell.CreateSolveType(ZOSAPI.Editors.SolveType.FNumber);
Solver._S_FNumber.FNumber = 3.1415;
Surface_Last.RadiusCell.SetSolveData(Solver);
SampleFile = System.IO.Path.Combine(TheApplication.SamplesDir, @"API\CS\e15_Seq_Optimization\OptimizedFile1.zos");
TheSystem.SaveAs(SampleFile);
//change BFL & run quick focus
Surface_Last.Thickness = 40.0;
IQuickFocus QFocus = tools.OpenQuickFocus();
QFocus.Criterion = QuickFocusCriterion.SpotSizeRadial;
QFocus.UseCentroid = true;
QFocus.Close();
SampleFile = System.IO.Path.Combine(TheApplication.SamplesDir, @"API\CS\e15_Seq_Optimization\OptimizedFile2.zos");
TheSystem.SaveAs(SampleFile);
//setup a few variables
ILDERow Surface5 = TheLDE.GetSurfaceAt(5);
ILDERow Surface6 = TheLDE.GetSurfaceAt(6);
ILDERow Surface9 = TheLDE.GetSurfaceAt(9);
ILDERow Surface10 = TheLDE.GetSurfaceAt(10);
ILDERow Surface11 = TheLDE.GetSurfaceAt(11);
//Thickness 2, 5, 6, 9, and 11 variable
Surface2.ThicknessCell.MakeSolveVariable();
//Thickness 10 pick up from 1
Solver = Surface10.ThicknessCell.CreateSolveType(ZOSAPI.Editors.SolveType.SurfacePickup);
ISolveSurfacePickup SolverPickup = Solver._S_SurfacePickup;
SolverPickup.Surface = 1;
SolverPickup.ScaleFactor = 1;
SolverPickup.Column = ZOSAPI.Editors.LDE.SurfaceColumn.Thickness;
Surface10.ThicknessCell.SetSolveData(Solver);
SampleFile = System.IO.Path.Combine(TheApplication.SamplesDir, @"API\CS\e15_Seq_Optimization\OptimizedFile3.zos");
TheSystem.SaveAs(SampleFile);
//define merit function
//load merit function
IMeritFunctionEditor TheMFE = TheSystem.MFE;
//Optimize for smallest RMS Spot, which is "Data" = 1
OptWizard.Data = 1;
OptWizard.OverallWeight = 1;
//Gaussian Quadrature with 3 rings (refers to index number = 2)
OptWizard.Ring = 2;
//Set air & glass boundaries
OptWizard.IsGlassUsed = true;
OptWizard.GlassMin = 3.0;
OptWizard.GlassMax = 15.0;
OptWizard.GlassEdge = 3.0;
OptWizard.IsAirUsed = true;
OptWizard.AirMin = 0.5;
OptWizard.AirMax = 1000.0;
OptWizard.AirEdge = 0.5;
//And click OK!
OptWizard.Apply();
string mf_filename = System.IO.Path.Combine(TheApplication.SamplesDir, @"API\CS\e15_Seq_Optimization\RMS_Spot_Radius.mf");
TheMFE.SaveMeritFunction(mf_filename);
TheMFE.LoadMeritFunction(mf_filename);
SampleFile = System.IO.Path.Combine(TheApplication.SamplesDir, @"API\CS\e15_Seq_Optimization\OptimizedFile4.zos");
// Run local optimization and measure time
// Local optimization until completion
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
ILocalOptimization LocalOpt = TheSystem.Tools.OpenLocalOptimization();
if (LocalOpt != null)
{
LocalOpt.Algorithm = ZOSAPI.Tools.Optimization.OptimizationAlgorithm.DampedLeastSquares;
LocalOpt.Cycles = ZOSAPI.Tools.Optimization.OptimizationCycles.Automatic;
LocalOpt.NumberOfCores = 8;
Console.WriteLine("Local Optimization...");
Console.WriteLine(String.Format("Initial Merit Function {0}", LocalOpt.InitialMeritFunction));
Console.WriteLine(String.Format("Final Merit Function {0}", LocalOpt.CurrentMeritFunction));
LocalOpt.Close();
}
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("Time elapsed : " + elapsedTime + "\n");
//Console.ReadKey(true);
// run global search
double GlobalOptimTimeInSeconds = 15;
IGlobalOptimization GlobalOpt = TheSystem.Tools.OpenGlobalOptimization();
if (GlobalOpt != null)
{
GlobalOpt.Algorithm = ZOSAPI.Tools.Optimization.OptimizationAlgorithm.DampedLeastSquares;
GlobalOpt.NumberOfCores = 8;
Console.WriteLine("Global Optimization for " + GlobalOptimTimeInSeconds.ToString() + " seconds...");
Console.WriteLine(String.Format("Initial Merit Function {0}", GlobalOpt.InitialMeritFunction));
GlobalOpt.NumberToSave = ZOSAPI.Tools.Optimization.OptimizationSaveCount.Save_10;
GlobalOpt.RunAndWaitWithTimeout(GlobalOptimTimeInSeconds);
for (int j = 1; j <= 10; j++)
{
Console.Write(String.Format("{0}: {1}\n", j, GlobalOpt.CurrentMeritFunction(j)));
}
GlobalOpt.Cancel();
GlobalOpt.WaitForCompletion();
GlobalOpt.Close();
}
//run hammer optimization
double HammerOptimTimeInSeconds = 15;
IHammerOptimization HammerOpt = TheSystem.Tools.OpenHammerOptimization();
if (HammerOpt != null)
{
HammerOpt.Algorithm = ZOSAPI.Tools.Optimization.OptimizationAlgorithm.DampedLeastSquares;
HammerOpt.NumberOfCores = 8;
Console.WriteLine("Hammer Optimization for " + HammerOptimTimeInSeconds.ToString() + " seconds...");
Console.WriteLine(String.Format("Initial Merit Function {0}", HammerOpt.InitialMeritFunction));
HammerOpt.RunAndWaitWithTimeout(HammerOptimTimeInSeconds);
Console.WriteLine(String.Format("Final Merit Function {0}", HammerOpt.CurrentMeritFunction));
HammerOpt.Cancel();
HammerOpt.WaitForCompletion();
HammerOpt.Close();
}
TheSystem.SaveAs(SampleFile);
Console.WriteLine("Press key to continue\n");
Console.ReadKey();
// Clean up
FinishStandaloneApplication(TheApplication);
}
static void FinishStandaloneApplication(IZOSAPI_Application TheApplication)
{
// Note - TheApplication will close automatically when this application exits, so this isn't strictly necessary in most cases
if (TheApplication != null)
{
TheApplication.CloseApplication();
}
}
static void LogInfo(string message)
{
// TODO - add custom logging
Console.WriteLine(message);
}
static void HandleError(string errorMessage)
{
// TODO - add custom error handling
throw new Exception(errorMessage);
}
}
}
Definition: ZemaxService.cs:198
IZOSAPI_Application CreateNewApplication()
Attempts to launch a new instance of Optic Studio in 'headless' mode. Note that although the Optic St...
Definition: ZemaxService.cs:864
Base interface for all analysis windows. This interface can be accessed via the I_Analyses interface.
Definition: IA_Base.cs:29
bool Terminate()
Attempt to cancel the currently running the analysis.
void WaitForCompletion()
Waits for the current analysis to finish running (if applicable).
IAS_ GetSettings()
Gets the settings for the current analysis.
IMessage ApplyAndWaitForCompletion()
Re-runs the analysis with the current settings and waits for it to finish calculating.
Base class for all analysis settings interfaces. This class can be accessed via the IA_ interface.
Definition: IAS_Base.cs:25
bool ModifySettings(string settingsFile, string typeCode, string newValue)
Changes a single setting in the specified file. See the MODIFYSETTINGS DDE command help documentation...
bool SaveTo(string settingsFile)
Saves the current settings to the specified file.
bool LoadFrom(string settingsFile)
Replaces the current settings with settings read from the specified file.
SolveStatus SetSolveData(ISolveData Data)
Updates the system with the new solve type settings (see also CreateSolveType and GetSolveData).
bool MakeSolveVariable()
Sets the solve type to SolveType.Variable.
ISolveData CreateSolveType(SolveType type)
Creates the solve type settings for the specified solve type. Note that SetSolveData must be used to ...
Base interface for all solve types. This interface can be accesed via the IEditorCell interface....
Definition: InterfacesEditors.cs:563
ISolveSurfacePickup _S_SurfacePickup
Definition: InterfacesEditors.cs:594
Definition: InterfacesEditors.cs:694
All data for a Lens Data Editor surface. This interface can be accessed via the ILensDataEditor inter...
Definition: InterfacesLDE.cs:791
IEditorCell ThicknessCell
Definition: InterfacesLDE.cs:1010
IEditorCell RadiusCell
Definition: InterfacesLDE.cs:990
This interface defines all properties and methods needed to interact with the Lens Data Editor....
Definition: InterfacesLDE.cs:265
ILDERow GetSurfaceAt(int SurfaceNumber)
Gets the data for the specified surface.
int NumberOfSurfaces
Gets the number of surfaces in the current system.
Definition: InterfacesLDE.cs:292
This interface defines all properties and methods needed to interact with the MRit Function Editor....
Definition: InterfacesMFE.cs:492
void LoadMeritFunction(string fileName)
Replaces the entire MFE with the specified file contents.
ISEQOptimizationWizard SEQOptimizationWizard
Get the Sequential Optimization Wizard; note that this wizard is obsolete and you should use SEQOptim...
Definition: InterfacesMFE.cs:648
void SaveMeritFunction(string fileName)
Saves the entire merit function to the specified file.
Represent a complete optical system. A IOpticalSystem corresponds to a single .ZMX file....
Definition: Interfaces.cs:687
void SaveAs(string fileName)
Saves the current system to the specified file. All future calls to Save will use the same file.
ISystemData SystemData
Data for configuring everything in the System Explorer.
Definition: Interfaces.cs:845
bool LoadFile(string LensFile, bool saveIfNeeded)
Replaces the current system with data from the specified file.
I_Analyses Analyses
Gets the analyses for the current system.
Definition: Interfaces.cs:925
ILensDataEditor LDE
Gets the lens data editor.
Definition: Interfaces.cs:865
IMeritFunctionEditor MFE
Gets the merit function editor.
Definition: Interfaces.cs:910
IOpticalSystemTools Tools
Gets an interface used to run various tools on the optical system.
Definition: Interfaces.cs:932
This interface contains all information about the current ZOS-API connection, as well as methods for ...
Definition: Interfaces.cs:261
bool IsValidLicenseForAPI
Gets a value indicating whether this the API is currently useable.
Definition: Interfaces.cs:287
ZOSAPI_Mode Mode
Gets the current connetion mode. Use this to check if Optic Studio is expecting a user operand / anal...
Definition: Interfaces.cs:306
LicenseStatusType LicenseStatus
Gets the license status. Note that this displays the license edition if successful,...
Definition: Interfaces.cs:280
void CloseApplication()
Shut down the Optic Studio process.
IOpticalSystem PrimarySystem
Gets the primary system. When Mode is ZOSAPI_Mode.Server, this will initially be an empty sequential ...
Definition: Interfaces.cs:328
string SamplesDir
Gets the full path for the current user's samples directory (in the My Documents\Zemax\Samples\ folde...
Definition: Interfaces.cs:505
System field data. This interface can be accessed via the IFields interface.
Definition: InterfacesSE.cs:977
IField AddField(double X, double Y, double Weight)
Add a new field, after all the current fields.
void SetFieldType(FieldType type)
Sets the field type definition for all fields.
bool MakeEqualAreaFields(int numberOfFields, double maximumField)
Replaces the existing system fields with new fields spread over an equal area.
IField GetField(int position)
Gets the specified field.
Interfaces and methods for changing all System Explorer data. This interface can be accessed via the ...
Definition: InterfacesSE.cs:275
IFields Fields
Definition: InterfacesSE.cs:278
IWavelengths Wavelengths
Definition: InterfacesSE.cs:277
bool SelectWavelengthPreset(WavelengthPreset preset)
Replaces all system wavelengths with a preset definition.
Interfaces and methods for running the Quick Focus tool. This interface can be accessed via the IOpti...
Definition: Tools.cs:793
Methods to run various system-wide tools. This interface can be accessed via the IOpticalSystem inter...
Definition: Tools.cs:107
IQuickFocus OpenQuickFocus()
Opens the Quick Focus tool.
int SetAllRadiiVariable()
Makes all radii in the system variable.
bool RemoveAllVariables()
Removes all variables in the system.
bool RunAndWaitForCompletion()
Sames as calling Run followed by WaitForCompletion.
bool Close()
Closes this tool and frees up and associated resources.
bool Cancel()
Cancels the currently running asynchronous tool.
bool WaitForCompletion()
Waits for the asynchronous tool to complete.
RunStatus RunAndWaitWithTimeout(double timeOutSeconds)
Starts the tool running, and waits for it to complete with the specified timeout value....
Interfaces and methods for running a Global Optimization. This interface can be accessed via the IOpt...
Definition: Optimization.cs:109
double InitialMeritFunction
Definition: Optimization.cs:117
Interfaces and methods for running a Hammer Optimization. This interface can be accessed via the IOpt...
Definition: Optimization.cs:170
double InitialMeritFunction
Definition: Optimization.cs:178
double CurrentMeritFunction
Definition: Optimization.cs:179
Interfaces and methods for running a Local Optimization. This interface can be accessed via the IOpti...
Definition: Optimization.cs:50
double CurrentMeritFunction
Definition: Optimization.cs:71
double InitialMeritFunction
Definition: Optimization.cs:70
Interface for the Merit Function, Sequential Optimization Wizard These settings can be retrieved from...
Definition: InterfacesWizards.cs:293
void Apply()
Settings are set, perform the wizardry.
Definition: IAS_FieldCurvatureAndDistortion.cs:5
Definition: IAS_FieldCurvatureAndDistortion.cs:5
AnalysisIDM
All available analysis types. See the I_Analyses interface for more information.
Definition: I_Analyses.cs:15
Definition: InterfacesLDE.cs:8
Definition: InterfacesMFE.cs:12
Definition: InterfacesEditors.cs:12
Definition: InterfacesSE.cs:11
Definition: Tools.cs:697
QuickFocusCriterion
Definition: Tools.cs:767
Definition: Optimization.cs:9
Definition: FileSource.cs:4
Definition: InterfacesWizards.cs:10
The ZOSAPI namespace contains classes for initially connecting to zemax. See also ZOSAPI_Connection,...
Definition: IAS_FieldCurvatureAndDistortion.cs:5
ZOSAPI_Mode
Definition: Interfaces.cs:77

Connect with Ansys