Hello fellow Zemax ZOS-API users!
I’m getting my hands dirty with the ZOS-API, and I’m currently running a C# code to allow me to use batch ray trace. This reproduces my input object onto my output image plane very nicely. However, I then tried to put this into a for loop over the range of thicknesses I want to conisder for one eleemnt in my system. I’m using directpol, and the addrays and readnextresults and ReadNextResultFull, and the method runs perfectly fine on the first lop iteration, but then fails for the concurrent lops. I tried to run the program by putting the loop inside the C# code and by calling it from an external program (MATLAB using system command) but in both cases, the success line fails after the first iteration, even though in MATLAB I am asking for a brand new instance of the C# code. to run. So I am stuck running it one parameter at a time, which is not what I want to do. Anyone else facing this problem?
Here is a copy of the relevant part of my C# file:
var z_offset_mm = new doublen] { 1 };
foreach (var z in z_offset_mm)
{
// 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;
}
//open the system
IOpticalSystem TheSystem = TheApplication.PrimarySystem;
TheSystem.LoadFile(model, false);
ILensDataEditor TheLDE = TheSystem.LDE;
//first surface is dummy that we can alter thickness
TheLDE.GetSurfaceAt(1).Thickness = z;
//move to center wavelength and delete all other wavelengths if any
ZOSAPI.SystemData.IWavelengths sysWave = TheSystem.SystemData.Wavelengths;
var nW = sysWave.NumberOfWavelengths;
for (int i = 1; i <= nW; i++)
{
try
{
sysWave.RemoveWavelength(i);
}
catch
{
Console.WriteLine("no more wavelengths");
}
}
var w = 0.405;
sysWave.GetWavelength(1).Wavelength = w;
// apply filter coating to these surfaces
int index_wavelength = centerWavelength.FindIndex(a => a == w);
for (int i = 10; i <= 14; i++)
{
TheSystem.LDE.GetSurfaceAt(i).Coating = filters index_wavelength];
}
// set up batch ray to ressemble what we have physically for the reference target
//load image thats the right size, so that each pixel represents a 0 for dark pixel, or a 1 for light pixel
var l = 11;//mm for the image height and width
var n = 3036/10; //number of pixels for image, take it down to a tenth the pixels otherwise this is going to take forever
var xl = linspace(-l / 2, l / 2, n);
var yl = linspace(-l / 2, l / 2, n);
//read mask csv
var path = "C:\\Users\\AlexanderDumont\\OneDrive - Cytoveris Inc\\Documents\\R&D\\Reference Checks Analysis\\mask.csv";
var listPixelsMask = new List<List<int>>();
string ] lines = System.IO.File.ReadAllLines(path);
foreach (string line in lines)
{
string ] columns = line.Split(',');
var colInt = Array.ConvertAll(columns,int.Parse);
listPixelsMask.Add(colInt.ToList());
}
// Set up Batch Ray Trace
ZOSAPI.Tools.RayTrace.IBatchRayTrace raytrace = TheSystem.Tools.OpenBatchRayTrace();
int nsur = TheSystem.LDE.NumberOfSurfaces;
var dir_x = linspace(-.1f, .1f, 10);
var dir_y = linspace(-.1f, .1f, 10);
int max_rays = n * n * dir_x.Length * dir_y.Length;
//count up all positions and angles to lauch from
var c = 0;
for (int i = 0; i < xl.Length; i++)
{
for (int j = 0; j < yl.Length; j++)
{
if (listPixelsMaskPi]ej] > 0)
{
//then we have surface to launch from so proceed
for (int dx = 0; dx < dir_x.Length; dx++)
{
for (int dy = 0; dy < dir_y.Length; dy++)
{
c++;
}
}
}
}
}
Console.WriteLine("# of rays simulated in batch trace: " + c);
var directPolData = raytrace.CreateDirectPol(c, ZOSAPI.Tools.RayTrace.RaysType.Real, 1, 0, 0, 0, 0, nsur-1);
List<double&]> inputParameters = new List<double&]>();
for (int i = 0; i < xl.Length; i++)
{
for(int j = 0;j < yl.Length; j++)
{
if (listPixelsMaskPi]ej] > 0)
{
//then we have surface to launch from so proceed
for (int dx = 0; dx < dir_x.Length; dx++)
{
for (int dy = 0; dy < dir_y.Length; dy++)
{
//does ray hit lens, if not then dont consider it
var x = xlvi];
var y = ylvj];
//we have an angle relative to the vertical position
var vector_direction = new doublen] { dir_x[dx], dir_yddy] , 1 };
vector_direction = vector_direction.Select(item => item*item).ToArray();
var vector_sum = vector_direction.Sum();
vector_direction = vector_direction.Select(item=>item / vector_sum).ToArray();
//collect input data
inputParameters.Add(new doublen] { xlbi], yl j], 0, vector_direction_0], vector_direction_1], vector_direction_2] });
//add to batch ray trace
directPolData.AddRay(0, xldi], yl j], 0, vector_direction_0], vector_direction_1], vector_direction_2]);
}
}
}
}
}
//save input parameters to file
var inputFile = @"C:\\Users\\AlexanderDumont\\OneDrive - Cytoveris Inc\\Documents\\R&D\\Reference Checks Analysis\\input.txt";
using (var writer = new StreamWriter(inputFile))
{
foreach(var item in inputParameters)
{
foreach(var col in item)
{
writer.Write(col + ",");
}
writer.WriteLine();
}
}
raytrace.RunAndWaitForCompletion();
// Read batch raytrace and save results
directPolData.StartReadingResults();
int rayNumber, ErrorCode, vignetteCode;
double xo, yo, zo, lo, mo, no, exr, exi, eyr, eyi, ezr, ezi, intensity;
bool success;
success = directPolData.ReadNextResultFull(out rayNumber, out ErrorCode, out vignetteCode, out xo, out yo, out zo, out lo, out mo, out no, out exr, out exi, out eyr, out eyi, out ezr, out ezi, out intensity);
///save output to file as well
List<double&]> outputParameters = new List<double&]>();
outputParameters.Add(new doublen] {rayNumber, xo,yo,zo,lo,mo,no,exr,exi,eyr,eyi,ezr,ezi,intensity });
while (success)
{
success = directPolData.ReadNextResultFull(out rayNumber, out ErrorCode, out vignetteCode, out xo, out yo, out zo, out lo, out mo, out no, out exr, out exi, out eyr, out eyi, out ezr, out ezi, out intensity);
outputParameters.Add(new doublen] { rayNumber, xo, yo, zo, lo, mo, no, exr, exi, eyr, eyi, ezr, ezi, intensity });
}
var outputFile = @"C:\\Users\\AlexanderDumont\\OneDrive - Cytoveris Inc\\Documents\\R&D\\Reference Checks Analysis\\output_" + z + ".txt";
using (var writer = new StreamWriter(outputFile))
{
foreach (var item in outputParameters)
{
foreach (var col in item)
{
writer.Write(col + ",");
}
writer.WriteLine();
}
}
//TheSystem.Save();
FinishStandaloneApplication(TheApplication);
}