Skip to main content

ZOS-API interface 2024 R1

Example 08 - C#

Last update: 17.07.2025

C#

using System;
using ZOSAPI;
namespace CSharpStandaloneApplication1
{
class CSharpStandalone_08_NSCEDetectorData
{
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;
// Add your custom code here...
/*
-. load \Samples\NS\Scattering\ABg scattering surface.zos
1. delete object 3(specular ray blocking)
2. insert detector polar positioned at same pos as object 2
- retrieve obj 2 rotation matrix, match orientation
- size = 20
- remove material from obj 4
-. run ray trace
3/4. Save/Load Detector Data
5/6. get detector data for detector polar
- retrieve single - value data with GetDetectorPolarData()
- retrieve data grid(all pixels) with GetAllDetectorPolarDataSafe()
7/8. get detector rectangle data
- retrieve single - value data with GetDetectorData()
- retrieve data grid(all pixels) with GetAllDetectorDataSafe()
9/10. get coherent detector rectangle data
- retrieve single-value data with GetCoherentData()
- retrieve data grid (all pixels) with GetAllCoherentDataSafe()
*/
string file = "\\Samples\\Non-sequential\\Scattering\\ABg scattering surface.zos";
string DataDir = TheApplication.ZemaxDataDir;
string filepath = DataDir + file;
TheSystem.LoadFile(filepath, false);
// creates new directory
string strPath = System.IO.Path.Combine(TheApplication.SamplesDir, @"API\CS");
System.IO.Directory.CreateDirectory(strPath);
// delete unnecessary object from NSCE
TheSystem.NCE.RemoveObjectAt(3);
// Add detector polar, change radial size to 20mm
ZOSAPI.Editors.NCE.INCERow obj3 = TheSystem.NCE.InsertNewObjectAt(3);
obj3.ChangeType(DetectorPolar);
// Set the detector polar radial size to 20
obj3.GetCellAt(12).DoubleValue = 20; // cell 12 always corresponds to 'Par2' in the NSCE
// Co-locate object 3 with object 2 (here, could alternatively use Ref Object flag)
bool success = TheSystem.NCE.GetMatrix(2, out double R11, out double R12, out double R13, out double R21,
out double R22, out double R23, out double R31, out double R32, out double R33, out double Xo,
out double Yo, out double Zo);
obj3.XPosition = Xo;
obj3.YPosition = Yo;
obj3.ZPosition = Zo;
// Conversion from rotation matrix to tilts described in KBA "Rotation matrix and Tilt About X/Y/Z in OpticStudio"
obj3.TiltAboutX = (180 / Math.PI) * Math.Atan2(-1 * R23, R33);
obj3.TiltAboutY = (180 / Math.PI) * Math.Asin(R13);
obj3.TiltAboutZ = (180 / Math.PI) * Math.Atan2(-1 * R12, R11);
// remove ABSORB material from object 4
TheSystem.NCE.GetObjectAt(4).Material = "";
// Run ray trace
ZOSAPI.Tools.RayTrace.INSCRayTrace RayTrace = TheSystem.Tools.OpenNSCRayTrace();
RayTrace.ClearDetectors(0); // clear the old detector data!
RayTrace.ScatterNSCRays = true;
RayTrace.UsePolarization = false;
RayTrace.SplitNSCRays = false;
RayTrace.IgnoreErrors = true;
RayTrace.RunAndWaitForCompletion();
RayTrace.Close();
// The next two steps are technically unnecessary in this case; since we just ran the ray trace,
// the results are already there. But we demonstrate usage here anyways
// Save detector data -- allows ray trace results to be loaded later
// For detector polar, the file type is .DDP; for detector rectangle, it is .DDR
string DetectorPolarFile = TheApplication.ZemaxDataDir + "\\Samples\\API\\CS\\detector3polar.DDP";
string DetectorRectFile = TheApplication.ZemaxDataDir + "\\Samples\\API\\CS\\detector4rect.DDR";
TheSystem.NCE.SaveDetector(3, DetectorPolarFile);
TheSystem.NCE.SaveDetector(4, DetectorRectFile);
// Load detector data -- for analyzing previous ray trace results
// For detector polar, the file type is .DDP; for detector rectangle, it's .DDR
TheSystem.NCE.LoadDetector(3, TheApplication.ZemaxDataDir + "\\Samples\\API\\CS\\detector3polar.DDP", false);
TheSystem.NCE.LoadDetector(4, TheApplication.ZemaxDataDir + "\\Samples\\API\\CS\\detector4rect.DDR", false);
// Here we read in the detector polar data from ZOS
// GetPolarDetectorData() is very similar to the MF operand NSDP;
// can retrieve RMS (degrees), total power, chromatricity, etc. (see NSDP in OpticStudio help)
// Note: GetPolarDetectorData() uses an enumeration for data type, shown here
ZOSAPI.Editors.NCE.PolarDetectorDataType DataFlag_Power = ZOSAPI.Editors.NCE.PolarDetectorDataType.Power;
ZOSAPI.Editors.NCE.PolarDetectorDataType DataFlag_ChromX = ZOSAPI.Editors.NCE.PolarDetectorDataType.Cx;
ZOSAPI.Editors.NCE.PolarDetectorDataType DataFlag_ChromY = ZOSAPI.Editors.NCE.PolarDetectorDataType.Cy;
success = TheSystem.NCE.GetPolarDetectorData(3, -4, DataFlag_Power, out double DetPolarData_RadialRMS); // obj=3, pix=-4, data=power enum
success = TheSystem.NCE.GetPolarDetectorData(3, 0, DataFlag_ChromX, out double DetPolarData_ChromX); // obj=3, pix=0, data=chromaticityX enum
success = TheSystem.NCE.GetPolarDetectorData(3, 0, DataFlag_ChromY, out double DetPolarData_ChromY); // obj=3, pix=0, data=chromaticityY enum
// To retrieve the entire data array (power, tristim. X/Y/Z, etc. for each pixel)
// can use GetAllPolarDetectorDataSafe(), or GetAllPolarDetectorData().
// Note: GetPolarDetectorData use an enumeration for data type, shown here
ZOSAPI.Editors.NCE.PolarDetectorDataType DataFlag_TriX = ZOSAPI.Editors.NCE.PolarDetectorDataType.TriX;
ZOSAPI.Editors.NCE.PolarDetectorDataType DataFlag_TriY = ZOSAPI.Editors.NCE.PolarDetectorDataType.TriY;
ZOSAPI.Editors.NCE.PolarDetectorDataType DataFlag_TriZ = ZOSAPI.Editors.NCE.PolarDetectorDataType.TriZ;
// now, retrieve the pixel data array
double[,] DetPolarData_TriX = TheSystem.NCE.GetAllPolarDetectorDataSafe(3, DataFlag_TriX);
double[,] DetPolarData_TriY = TheSystem.NCE.GetAllPolarDetectorDataSafe(3, DataFlag_TriY);
double[,] DetPolarData_TriZ = TheSystem.NCE.GetAllPolarDetectorDataSafe(3, DataFlag_TriZ);
// Here we read in the detector rectangle data
// GetDetectorData() is very similar to the Merit Function operand NSDD
// can retrieve Std Dev, # of rays, total power, etc.; data calculated over whole detector or individual pixel
TheSystem.NCE.GetDetectorData(4, -4, 0, out double DetRectangleData_StdDev); // obj=4, pix=-4, data=0
// To retrieve the entire data array (flux, flux/area, etc.) for all pixel data,
// can use GetAllDetectorDataSafe() or GetAllDetectorData().
// The 'Data' inputs for these functions (parameter 2) can be found in the API syntax help,
// under the listing for GetDetectorData.
double[,] DetRectangleData_Flux = TheSystem.NCE.GetAllDetectorDataSafe(4, 0); // total flux on each pixel
double[,] DetRectangleData_FluxArea = TheSystem.NCE.GetAllDetectorDataSafe(4, 1); // flux/area on each pixel
double[,] DetRectangleData_FluxSAP = TheSystem.NCE.GetAllDetectorDataSafe(4, 2); // flux/solid angle on each pixel
// Finally, let's read coherent data.
// The coherent data is meaningless in this example, but it serves to demonstrate API usage and functionality.
// Read in the detector rectangle coherent data
// GetCoherentData() is very similar to the operand NSDC
// Can retrieve real, imaginary, amplitude, power, with 'data' input
// for pix = 0, get sum on detector; pix > 0 gives single pixel data
TheSystem.NCE.GetCoherentData(4, 0, ZOSAPI.Editors.NCE.DetectorDataType.Amplitude, out double DetRectangle_CoherentAmp); // obj=4, pix=0, data=2
TheSystem.NCE.GetCoherentData(4, 0, ZOSAPI.Editors.NCE.DetectorDataType.Power, out double DetRectangle_CoherentPower); // obj=4, pix=0, data=3
// Retrieve whole data array with GetAllCoherentDataSafe(), or GetAllCoherentData().
// The 'Data' input functions similarly to NSDC(real, imaginary, amplitude, power)
// Note: divide coherent power by pixel area to get coherent irradiance
double[,] DetRectangle_CoherentPowerFull = TheSystem.NCE.GetAllCoherentDataSafe(4, ZOSAPI.Editors.NCE.DetectorDataType.Power); // obj=4, data=3
string OutFile = DataDir + "\\Samples\\API\\CS\\CS_08_NSCEDetectorData.zos";
TheSystem.SaveAs(OutFile);
// from here, we can plot or analyze any detector data we want!
// 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:863
double DoubleValue
Gets or sets the double precision value of this cell. Note that if DataType is not CellDataType....
Definition: InterfacesEditors.cs:340
IEditorCell GetCellAt(int pos)
Gets the cell at the specified index (IEditor.MinColumn to IEditor.MaxColumn).
All data for a Non-Sequential Component Editor object. This interface can be accessed via the INonSeq...
Definition: InterfacesNCE.cs:1198
bool ChangeType(IObjectTypeSettings settings)
Changes the current object to the specified type. Use GetObjectTypeSettings to get the relevant setti...
IObjectTypeSettings GetObjectTypeSettings(ObjectType type)
Create the settings for the specified type. Use this method to specify any extra data required to cha...
This interface is used for selecting any files required by a object, and for changing object types....
Definition: InterfacesNCE.cs:1110
Represent a complete optical system. A IOpticalSystem corresponds to a single .ZMX file....
Definition: Interfaces.cs:690
void SaveAs(string fileName)
Saves the current system to the specified file. All future calls to Save will use the same file.
bool LoadFile(string LensFile, bool saveIfNeeded)
Replaces the current system with data from the specified file.
INonSeqEditor NCE
Gets the non-sequential component editor.
Definition: Interfaces.cs:887
IOpticalSystemTools Tools
Gets an interface used to run various tools on the optical system.
Definition: Interfaces.cs:935
This interface contains all information about the current ZOS-API connection, as well as methods for ...
Definition: Interfaces.cs:264
bool IsValidLicenseForAPI
Gets a value indicating whether this the API is currently useable.
Definition: Interfaces.cs:290
ZOSAPI_Mode Mode
Gets the current connetion mode. Use this to check if Optic Studio is expecting a user operand / anal...
Definition: Interfaces.cs:309
string ZemaxDataDir
Gets the full path for the current user's Zemax directory (in the My Documents\Zemax\ folder by defau...
Definition: Interfaces.cs:527
LicenseStatusType LicenseStatus
Gets the license status. Note that this displays the license edition if successful,...
Definition: Interfaces.cs:283
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:331
string SamplesDir
Gets the full path for the current user's samples directory (in the My Documents\Zemax\Samples\ folde...
Definition: Interfaces.cs:508
Interfaces and methods for running a non-sequential ray trace. This interface can be accessed via the...
Definition: RayTrace.cs:45
@ RayTrace
Single Ray Trace.
Definition: InterfacesNCE.cs:19
PolarDetectorDataType
Definition: InterfacesNCE.cs:262
Definition: InterfacesEditors.cs:12
The ZOSAPI namespace contains classes for initially connecting to zemax. See also ZOSAPI_Connection,...
Definition: IAS_FieldCurvatureAndDistortion.cs:5
ZOSAPI_Mode
Definition: Interfaces.cs:80

Connect with Ansys