Solved

Reading analysis header lines with C++

  • 26 October 2023
  • 2 replies
  • 78 views

Userlevel 7
Badge +3

I’m writing a user-defined merit function operand in C++ and would like to read the header lines from an analysis window (and then parse the results to extract numerical values of interest).  For example, in POP, the header contains several useful numbers related to the analysis results. 

Using Matlab, this is fairly simple as @Allie discusses here:

 

However, it appears that in C++ the header lines are passed using SAFEARRAY.  There is one example (#23) that shows how this is done for numerical arrays (see below). 

Just curious if someone might know how to do something similar for the header lines?  Is it possible to get the header lines in the form of a string array?  If so, a simple example would be greatly appreciated! 

Thanks,

Jeff

 

icon

Best answer by MichaelH 26 October 2023, 20:57

View original

2 replies

Userlevel 6
Badge +2

Hey Jeff, 

First, I would STRONGLY recommend using C# rather than C++ for ZOS-API applications.  C# directly uses .NET while C++ has to use COM to communicate with the ZOS-API.  C# is easier to use (especially considering COM) and there are more Zemax users that can help with C#. 

// C#
// Add your custom code here...
// open new POP window
var win = TheSystem.Analyses.New_Analysis_SettingsFirst(ZOSAPI.Analysis.AnalysisIDM.PhysicalOpticsPropagation);

// change POP settings here
var settings = win.GetSettings() as ZOSAPI.Analysis.PhysicalOptics.IAS_PhysicalOpticsPropagation;

// run POP analysis
win.ApplyAndWaitForCompletion();

// get the results
var results = win.GetResults();
foreach(var line in results.HeaderData.Lines)
{
Console.WriteLine(line);
}

If you remember trying to use Python prior to 2018, it was an absolute nightmare; before 2018 Python used COM to connect to the ZOS-API so I researched and created the current Python template using PythonNET.  Now C#, Mathematica, Matlab and Python all use .NET to directly connect to the ZOS-API and C++ is the only outlier.

If you have to use C++, here is how you can get the header data:

// C++
// Add your custom code here...
// open new POP window
auto win = TheSystem->Analyses->New_Analysis(AnalysisIDM::AnalysisIDM_PhysicalOpticsPropagation);

// change POP settings here
IAS_PhysicalOpticsPropagationPtr settings = win->GetSettings();

// run POP analysis
win->ApplyAndWaitForCompletion();

// get the results
auto results = win->GetResults();
SAFEARRAY* psa = results->HeaderData->Lines;

// Get a pointer to the elements of the array.
BSTR HUGEP* pbstr;
HRESULT hr = SafeArrayAccessData(psa, (void HUGEP**) & pbstr);

// make sure we can actually get data from the safearray
if (SUCCEEDED(hr)) {
// sizeof is off-by-1 to account for NUL terminater at end of array
for (long i = 0; i < sizeof(pbstr) - 1; i++)
wcout << pbstr[i] << endl;
}
SafeArrayUnaccessData(psa);

If you need help writing a compiled C# UDOC, you can DM me and I’d be glad to help.

Userlevel 7
Badge +3

Hi Michael,

Perfect, thanks so much!  I had a working UDOC written in C++ and just wanted to modify it to include results taken from a header.  With your help it’s all good now.

I appreciate your guidance regarding use of C#.  Generally I try to do as much as I can in Matlab, and venture into C-code only when necessary.  Since I had a little bit of previous experience with C++ I just opted to go that route.  However, I have a newfound appreciation for the simplicity of using .NET for ZOS-API purposes.

In the future, if I start a new user extension/analysis/operand then I will definitely take a look at C#. 

Thanks again!
Jeff

Reply