Example 15 - C#
Last update: 17.07.2025C#
using System;
using System.Diagnostics;
using System.Threading;
using ZOSAPI;
using ZOSAPI.Analysis;
using ZOSAPI.Analysis.Settings;
using ZOSAPI.Editors;
using ZOSAPI.Editors.LDE;
using ZOSAPI.Editors.MFE;
using ZOSAPI.SystemData;
using ZOSAPI.Tools;
using ZOSAPI.Tools.General;
using ZOSAPI.Tools.Optimization;
using ZOSAPI.Wizards;
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
// 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;
}
{
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
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
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
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
// 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
analysis.ApplyAndWaitForCompletion();
// remove all variables and add a F# solve on last surface radius
ILensDataEditor TheLDE = TheSystem.LDE;
IOpticalSystemTools tools = TheSystem.Tools;
tools.RemoveAllVariables();
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.RunAndWaitForCompletion();
QFocus.Close();
SampleFile = System.IO.Path.Combine(TheApplication.SamplesDir, @"API\CS\e15_Seq_Optimization\OptimizedFile2.zos");
TheSystem.SaveAs(SampleFile);
//setup a few variables
tools.SetAllRadiiVariable();
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();
Surface5.ThicknessCell.MakeSolveVariable();
Surface6.ThicknessCell.MakeSolveVariable();
Surface9.ThicknessCell.MakeSolveVariable();
Surface11.ThicknessCell.MakeSolveVariable();
//Thickness 10 pick up from 1
ISolveSurfacePickup SolverPickup = Solver._S_SurfacePickup;
SolverPickup.Surface = 1;
SolverPickup.ScaleFactor = 1;
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;
ISEQOptimizationWizard OptWizard = TheMFE.SEQOptimizationWizard;
//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.NumberOfCores = 8;
Console.WriteLine("Local Optimization...");
LocalOpt.RunAndWaitForCompletion();
LocalOpt.Close();
}
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
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.NumberOfCores = 8;
Console.WriteLine("Global Optimization for " + GlobalOptimTimeInSeconds.ToString() + " seconds...");
GlobalOpt.RunAndWaitWithTimeout(GlobalOptimTimeInSeconds);
for (int j = 1; j <= 10; j++)
{
}
GlobalOpt.Cancel();
GlobalOpt.WaitForCompletion();
GlobalOpt.Close();
}
//run hammer optimization
double HammerOptimTimeInSeconds = 15;
IHammerOptimization HammerOpt = TheSystem.Tools.OpenHammerOptimization();
if (HammerOpt != null)
{
HammerOpt.NumberOfCores = 8;
Console.WriteLine("Hammer Optimization for " + HammerOptimTimeInSeconds.ToString() + " seconds...");
HammerOpt.RunAndWaitWithTimeout(HammerOptimTimeInSeconds);
HammerOpt.Cancel();
HammerOpt.WaitForCompletion();
HammerOpt.Close();
}
TheSystem.SaveAs(SampleFile);
Console.WriteLine("Press key to continue\n");
Console.ReadKey();
// Clean up
FinishStandaloneApplication(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
void WaitForCompletion()
Waits for the current analysis to finish running (if applicable).
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
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
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.
Interfaces and methods for changing all System Explorer data. This interface can be accessed via the ...
Definition: InterfacesSE.cs:275
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 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
double CurrentMeritFunction(int N)
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
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
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