Skip to main content
Solved

Zernike Alteration in Python API

  • September 9, 2020
  • 8 replies
  • 329 views

Does anyone have an example (or is there one in the zemax documentation) for altering the number of zernike terms and the terms themselves using a python API?

Best answer by Ali H

Hi Chase,


You may use code similar to below to get/set the number of Zernike terms and set the values of the coefficients:



TheLDE = TheSystem.LDE
surf3 = TheLDE.GetSurfaceAt(3)
surf3.SurfaceData.NumberOfTerms = 5
surf3.GetSurfaceCell(ZOSAPI.Editors.LDE.SurfaceColumn.Par15).DoubleValue = 5.3


Best,


Ali

View original
Did this topic help you find an answer to your question?

8 replies

Ali H
Forum|alt.badge.img+1
  • Visible
  • 32 replies
  • Answer
  • September 10, 2020

Hi Chase,


You may use code similar to below to get/set the number of Zernike terms and set the values of the coefficients:



TheLDE = TheSystem.LDE
surf3 = TheLDE.GetSurfaceAt(3)
surf3.SurfaceData.NumberOfTerms = 5
surf3.GetSurfaceCell(ZOSAPI.Editors.LDE.SurfaceColumn.Par15).DoubleValue = 5.3


Best,


Ali


  • Author
  • Single Emitter
  • 2 replies
  • September 10, 2020

Thanks Ali,


Does it work similarily in Non-sequential? Also, what is the command for reading the parameter that is already there?


Chase


Ali H
Forum|alt.badge.img+1
  • Visible
  • 32 replies
  • September 10, 2020

Hi Chase,


Yes, it is similar in non-sequential . The code in NSC for a Zernike Surface as Object number 3 would be:



TheNCE = TheSystem.NCE
obj3 = TheNCE.GetObjectAt(3)
numTerms = obj3.ObjectData.NumberOfZTerms
Z1 = obj3.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par16).DoubleValue

The above code gets the values that are currently set for the number of terms and Z1. Just to clarify:


to get a value and assign it to the variable Z1 you could use:


Z1 = obj3.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par16).DoubleValue


to set a value you could use:


obj3.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par16).DoubleValue = 3.0


Best,


Ali


  • Author
  • Single Emitter
  • 2 replies
  • September 10, 2020

Awesome, Thank you!


s.ng
  • Monochrome
  • 4 replies
  • November 23, 2022

This code did not work for me.  Did something change in the API?
I get an error:

System.ArgumentException: Expected Double, got 'String'
   at ZemaxUI.ZOSAPI.Editors.ZOSAPI_EditorCellBase.set_DoubleValue(Double value)

for the line: 

surf3.GetSurfaceCell(ZOSAPI.Editors.LDE.SurfaceColumn.Par15).DoubleValue = 5.3

Ethan
En-Lightened
Forum|alt.badge.img+2
  • En-Lightened
  • 107 replies
  • January 13, 2023

Hi @s.ng,

That line of code should still work. Double check that there aren’t any strange characters (possibly white space) that were appended if you copy and pasted it straight out of the post. My first impression is that it is acting like 5.3 is a string, so just make sure that it is indeed interpreted as a Double.

If that doesn’t work, can you share a larger snippet of your code so that we can check for errors?

Best,
Ethan


ejh
  • Single Emitter
  • 3 replies
  • January 8, 2025

This does not work for me either. For some reason only up to Par4 works --- whereas the Zernike terms only start at Par16. It works fine for Material, decentres, tilts etc. I’ve been testing this and have done the checks to convert to double. They are not working for me… anyway the exact same 0.0 works for the other parameters. I remember there being a bug in the API enumeration for surface types, where a Zernike Standard Phase surface would give a ZonePlate… My impression would be that this is from the same family of problems?

 

zernike_surface.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par1).DoubleValue += 0.0

zernike_surface.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par2).DoubleValue += 0.0

zernike_surface.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par3).DoubleValue += 0.0

zernike_surface.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par4).DoubleValue += 0.0

zernike_surface.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par5).DoubleValue += 0.0
*** System.ArgumentException: Expected Double, got 'String'
   at ZemaxUI.ZOSAPI.Editors.ZOSAPI_EditorCellBase.get_DoubleValue()

zernike_surface.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par16).DoubleValue += 0.0
*** System.ArgumentException: Expected Double, got 'String'
   at ZemaxUI.ZOSAPI.Editors.ZOSAPI_EditorCellBase.get_DoubleValue()

 

Or

 

TheNCE = TheSystem.NCE

obj2 = TheNCE.GetObjectAt(2)
Z1 = 0.0
Z1 = obj2.GetObjectCell(ZOSAPI.Editors.NCE.ObjectColumn.Par16).DoubleValue
*** System.ArgumentException: Expected Double, got 'String'
   at ZemaxUI.ZOSAPI.Editors.ZOSAPI_EditorCellBase.get_DoubleValue()

 


ejh
  • Single Emitter
  • 3 replies
  • January 10, 2025

My bad, I solved this for my case. In all my confusion I was trying to access the incorrect surface. If it helps anyone I’m doing this recursively to go through the first 21 Zernike terms for several Zernike surfaces that a non-sequential objects in a mixed mode model.

 

            # Original Zernike values, padded to 21 terms where the first 4 are 0.0
            zernike_values = {
                "zpif": [0.0, 0.0, 0.0, 0.0, 4.52E-08, -2.81E-06, -4.88E-07, 1.73E-06, -1.81E-07, -7.25E-07, 1.65E-07, 1.89E-06, -2.41E-07, -6.27E-09, -7.15E-07, -2.01E-07, -7.92E-08, -6.08E-07, 5.01E-08, 5.72E-07, 1.57E-07],
                "zpi1": [0.0, 0.0, 0.0, 0.0, -2.00E-06, -8.98E-06, -2.00E-05, 5.82E-06, -1.87E-05, -7.01E-06, 8.95E-06, 9.70E-06, -1.67E-06, 8.18E-06, -1.55E-05, -5.87E-07, 4.49E-06, 4.32E-06, -2.65E-06, -7.77E-06, -1.27E-06],
                "zpi2": [0.0, 0.0, 0.0, 0.0, 3.05E-06, -9.17E-06, 2.22E-05, 7.80E-06, 1.85E-05, -5.63E-06, 9.34E-06, 1.08E-05, -2.06E-07, 7.29E-06, 1.33E-05, -7.75E-07, -5.55E-06, 4.33E-06, 2.74E-06, -7.43E-06, 1.96E-06],
                "zpi3": [0.0, 0.0, 0.0, 0.0, 4.46E-05, -2.21E-05, -1.33E-05, 1.62E-05, -1.59E-05, 2.06E-05, 1.97E-06, -1.73E-05, -2.08E-05, -4.39E-05, 1.75E-05, -6.15E-06, -1.38E-07, 7.77E-06, -1.30E-05, -1.58E-05, 1.08E-05],
            }
            
            # Function to generate randomized values with +/- 80% variation
            def generate_randomized_zernike(zernike_values):
                randomized_zerns = {}
                for key, values in zernike_values.items():
                    randomized_zerns[key] = []  # Initialize an empty list for each key
                    
                    for i, value in enumerate(values):
                        if i < 4:
                            # Terms 1 to 4 remain zero
                            randomized_zerns[key].append(0.0)
                        else:
                            # Apply random variation for terms 5 to 21
                            variation = value * random.uniform(-0.8, 0.8)  # +/- 80% variation
                            randomized_zerns[key].append(value + variation)
                
                return randomized_zerns
            
            # Generate the randomized Zernike terms
            randomized_zernike = generate_randomized_zernike(zernike_values)
            
            # Verify the output
            for key, values in randomized_zernike.items():
                print(f"{key}: {len(values)} terms")
                print(values) 

 

 

…..

 

        elif 'zernike_dict' in surface:
            # Zernike surface actions
            print(f"\nProcessing Zernike surface: {surface['name']}")
            zernike_dict = surface['zernike_dict']
            zernike_surface = surface['surface']
            
            
                       
            # Loop through Zernike terms
            for zernike_index, zernike_value in zernike_dict.items():
                zernike_term_number = int(zernike_index[2:])  # Extract term number from 'zt#'
                parameter_column = ZOSAPI.Editors.NCE.ObjectColumn.Par16 + (zernike_term_number - 1)  # Start at Par16
                print(f"Processing Zernike term {zernike_term_number}: parameter_column = {parameter_column}")
            
                # Access the cell using parameter_column
                cell = zernike_surface.GetObjectCell(parameter_column)
                print(f"Cell type for parameter_column {parameter_column}: {type(cell)}")
            
                # Ensure the value is set as a float
                try:
                    cell.DoubleValue += float(zernike_value)
                except AttributeError as e:
                    print(f"Cell at parameter_column {parameter_column} does not support DoubleValue. Error: {e}")
                except Exception as e:
                    print(f"Unexpected error while setting DoubleValue for parameter_column {parameter_column}: {e}")


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings