Skip to main content

I have no issues using the code line in Zemax Programming Interactive Mode

# mark cell as V
# Surface 18 - LDE row number for compensator
# Cell 15 - Decenter X/Y or Tilt X/Y/Z
TheSystem.LDE.GetSurfaceAt(18).GetCellAt(15).MakeSolveVariable()

But it raises the following error when I program and try to use it in a Standalone application mode.

Error1


Any ideas on why this happens?

Forgot to add info: Using Python 3.13.2 and Pythonnet 3.0.5


Are you sure the cell is active and correct?  If you try to make the Par1 cell on a Standard Surface variable, you’ll get a similar error since Par1 is not an active cell.  I would include a GetCellAt(SurfCell).IsActive and GetCellAt(SurfCell).Header to check if the column is active and to get what the header name (for debugging).


Thanks ​@MichaelH : What exactly do mean by making a cell Active? What designates a cell as Inactive vs Active?

Also Surface#18 is a Coordinate Break surface. Do I have to treat Coordinate Break surfaces differently from standard surfaces in ZOS-API?

Cheers!


@MichaelH : Tried your suggestion, as it turns out you were right - there is something not right about Surface18. As you can see in the screenshot below - Surface18 is a Coordinate break surface.

compSurf = TheSystem.LDE.GetSurfaceAt(18) # read surface 18
A = compSurf.GetCellAt(15).Header
compSurf.GetCellAt(15).IsActive # check if cell15 is active

 

Header is NULL. Why? 


@Asuku 

 

I made a dummy file with 24 surfaces (arbitrarily) in the LDE and changed Surface 18 to a Coordinate Break.

I then ran both snippets:

TheSystem.LDE.GetSurfaceAt(18).GetCellAt(15).MakeSolveVariable()  
compSurf = TheSystem.LDE.GetSurfaceAt(18) # read surface 18
A = compSurf.GetCellAt(15).Header
compSurf.GetCellAt(15).IsActive # check if cell15 is active

In Interactive and Standalone.

No issues on my side except that in 2025 R1.00 I still have this graphical bug (the solve is a bit hidden when selected):

This is a known issue I believe, and is reported there:

I upgraded Python to 3.13.5 and Pythonnet to 3.0.3 for the test.

You may want to consider sharing a simplified file that demonstrates the issue for further troubleshooting. Could you confirm that you are running the code on the exact same file?

Take care,

 

David


Hello ​@David.Nguyen & ​@MichaelH : Please disregard my previous post. My previous post has an error in the code. Here is the corrected version.

Here is the MWE (minimal working example) to demonstrate the error message. I have also attached a 7Z file with the model and python code.

I am using Python 3.12.6 and Pyhonnet 3.0.5

Model:

Code:

if __name__ == '__main__':
zos = PythonStandaloneApplication() # open bridge to zemax ZOS API

# instantiate zos
ZOSAPI = zos.ZOSAPI
TheApplication = zos.TheApplication
TheSystem = zos.TheSystem

ZemaxDesignFilePath = r"C:\Users\user1\Desktop\MWE_NEW\MWE_v1.zmx"

print(f'\nZemax model: {ZemaxDesignFilePath}') # print full path
testFile = ZemaxDesignFilePath
TheSystem.LoadFile(ZemaxDesignFilePath, False)
TheLDE = TheSystem.LDE


compensatorSurfNum = u3] # enter compensator surface row #s from Zemax design LDE
compensatorSurfTh = True
compensatorSurfCells = f15] # 15 is tY - use only tY for now
# TODO apply compSurface param (thickness, radius, par1...parN) to variable solve
# TODO convert initialCompValue to array to hold multiple compensator initial values
for c in range(len(compensatorSurfNum)):
compSurf = TheSystem.LDE.GetSurfaceAt(compensatorSurfNumo0])
if compensatorSurfTh:
compSurf.ThicknessCell.MakeSolveVariable()
initialCompThValue = compSurf.Thickness # record the initial value of the cell
for SurfCell in compensatorSurfCells:
TheSystem.LDE.GetSurfaceAt(compensatorSurfNumo0]).GetCellAt(SurfCell).CreateSolveType(ZOSAPI.Editors.SolveType.Variable ) # mark cell as V
initialCompValue = compSurf.Thickness # record the initial value of the cell

# This will clean up the connection to OpticStudio.
# Note that it closes down the server instance of OpticStudio, so you for maximum performance do not do
# this until you need to.
del zos
zos = None

Error:

 


I have made an observation!

Looks like there is nothing inherently wrong with the way I code or with the model. BUT, looks like the problem I am facing has to do with file path length limit. In general, WINDOWS traditionally limits file path to MAX of 260 chars. I believe OpticStudio by itself (and so does ZOS-API follows this limit).

 

I copied the same ZMX files onto my desktop and the code executes fine with a total length of 159 chars.

However, the total number of chars to the Zemax file in my original work folder = 262 chars and this seems to be the problem.

 

Is anyone else aware of this pathlength limit criteria in Zemax/ZOS-API? or am I completely out of my depths here? 


@Asuku 

 

This might be relevant:

Take care,

 

David


I always like to check that my file is loaded properly before attempting any calculation on the file.  So, a future debugging technique, I would always use code like below:
 

TheSystem.LoadFile(ZemaxDesignFilePath)
if TheSystem.Mode == ZOSAPI.SystemType.Sequential:
assert TheSystem.SystemData.Aperture.ApertureValue > 0 or TheSystem.LDE.NumberOfSurfaces != 3, "Sequential system could not load"
else:
assert TheSystem.NCE.NumberOfObjects > 1 or TheSystem.NCE.GetObjectAt(1).Type != ZOSAPI.Editors.NCE.ObjectType.NullObject, "Non-sequential system could not load"

This checks to make sure a sequential system either has more than the default 3 surfaces or has an aperture value greater than 0 (so that rays can trace); if the system is non-sequential, it makes sure the system is not the default single object Null Object.  This works even if your Default Startup in the GUI has a different file than the LENS.ZMX.  This code snippet has saved me countless hours of debugging when my filepath is invalid.


Hi all: I have tested the theory of Path Length limit and that seems to solve all the issues.

Closing this thread and marking ​@MichaelH answer as solution. I would also add another Try/Except logic to Michael’s answer to check the absolute path length to your Zemax file is < 260 chars.

Thanks for taking time. Cheers!


Reply