Skip to main content
Solved

Batch Ray Trace: adapt "toSurface" in loop


Sander

Hi all,

I am using BatchRayTrace with the ZOSapi in OpticStudio 230724 and python 3.9.

Following example 22, I am able to raytrace and extract the results into x_ary and y_ary. Subsequently I calculate the geometric radius using x_ary and y_ary. So far so good

Afterwards  I want to use BatchRayTrace with a different surface and calculate the geometric radius again at the updated surface.

Problem: I cannot update the “toSurface”. The first call of raytrace.CreateNormUnpol(max_rays, ZOSAPI.Tools.RayTrace.RaysType.Real, surf_i) seems to define the “toSurface”. It cannot be changed even, if I close the tool and open a new one with the new surface: It always calculates the exact same output as before.

 

Does anyone tried to update “toSurface” of the BatchRayTrace -Tool in a loop before?

Is there anything else to do to update the “toSurface” in addition to closing the Tool?

 

Here is my code snipped:

 

# Define batch ray trace constants
    hx = 0.0
    hy = 0.0
    num_fields = TheSystem.SystemData.Fields.NumberOfFields
    
    nsur = TheSystem.LDE.NumberOfSurfaces
    max_rays = 10000
    surf_s      = np.array([15,16,17,18,19,20,21]) # surfaces where spot size will be measured
    
    spots_rms   = np.zeros((surf_s.shape))
    spots_geo   = np.zeros((surf_s.shape))

    # Initialize x/y image plane arrays
    x_ary  = np.empty((surf_s.size, max_rays))
    y_ary  = np.empty((surf_s.size, max_rays))
    r_ary  = np.empty((surf_s.size, max_rays))
    
    wave = 0

        
    for surf_idx in range(0, len(surf_s)):
        
        # Set up Batch Ray Trace for surface_i=camera_i
        raytrace = TheSystem.Tools.OpenBatchRayTrace()
        surf_i = int(surf_s[surf_idx])
        print('raytrace to surface %d' % surf_i)
        normUnPolData = raytrace.CreateNormUnpol(max_rays, ZOSAPI.Tools.RayTrace.RaysType.Real, surf_i)
        normUnPolData.ClearData()
        for ii in range(1, max_rays + 1):

            px = np.random.random() * 2 - 1
            py = np.random.random() * 2 - 1
            
            while (px*px + py*py > 1):
                py = np.random.random() * 2 - 1  
            normUnPolData.AddRay(wave, hx, hy, px, py, Enum.Parse(ZOSAPI.Tools.RayTrace.OPDMode, "None"))
        
        raytrace.RunAndWaitForCompletion()

        # Read batch raytrace and display results
        normUnPolData.StartReadingResults()
        
        # Python NET requires all arguments to be passed in as reference, so need to have placeholders
        sysInt = Int32(1)
        sysDbl = Double(1.0)
        
        output = normUnPolData.ReadNextResult(sysInt, sysInt, sysInt,
                        sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl);
        

        while output[0]:                                                    # success
            if ((output[2] == 0) and (output[3] == 0)):                     # ErrorCode & vignetteCode
                x_ary[surf_idx, output[1] - 1] = output[4]   # X
                y_ary[surf_idx, output[1] - 1] = output[5]   # Y
            else:
                x_ary[surf_idx, output[1] - 1] = None   # X
                y_ary[surf_idx, output[1] - 1] = None   # Y
            output = normUnPolData.ReadNextResult(sysInt, sysInt, sysInt,
                        sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl, sysDbl);
        
        
        r_ary[surf_idx, :] = np.sqrt(x_ary[surf_idx,:]**2 + y_ary[surf_idx,:]**2)
        
        spots_geo[surf_idx] = np.nanmax( r_ary[0,:] )*1000
        spots_rms[surf_idx] = np.sqrt(np.nanmean( r_ary[0,:]**2))*1000
        print('   RMS radius: %6.3f' %  spots_rms[surf_idx] )
        print('   GEO radius: %6.3f' %  spots_geo[surf_idx] )
        
        raytrace.Close() # need to close for updating System
        del raytrace
        del normUnPolData
        print("deleted raytrace")

 

Best answer by David.Nguyen

Hi @Sander,

 

It doesn’t have to do with the BatchRayTrace. Those are the lines that cause the issue I believe:

spots_geo[surf_idx] = np.nanmax( r_ary[0,:] )*1000
spots_rms[surf_idx] = np.sqrt(np.nanmean( r_ary[0,:]**2))*1000

Instead of using 

r_ary[surf_idx, :]

You are always using surf_idx = 0.

It took me quite a while to figure out. In the future, I think it would help if you simplify your code before sending it on the Community. You can read more about it here: https://stackoverflow.com/help/minimal-reproducible-example.

I hope it helps.

Take care,


David

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

2 replies

David.Nguyen
Luminary
Forum|alt.badge.img+2
  • Luminary
  • 1089 replies
  • Answer
  • October 2, 2023

Hi @Sander,

 

It doesn’t have to do with the BatchRayTrace. Those are the lines that cause the issue I believe:

spots_geo[surf_idx] = np.nanmax( r_ary[0,:] )*1000
spots_rms[surf_idx] = np.sqrt(np.nanmean( r_ary[0,:]**2))*1000

Instead of using 

r_ary[surf_idx, :]

You are always using surf_idx = 0.

It took me quite a while to figure out. In the future, I think it would help if you simplify your code before sending it on the Community. You can read more about it here: https://stackoverflow.com/help/minimal-reproducible-example.

I hope it helps.

Take care,


David


Sander
  • Author
  • Single Emitter
  • 1 reply
  • October 2, 2023

Hi David,

 

Thank you so much for spotting this. It works now!

It would have been helpful to find any example showcasing BatchRayTrace with toSurface not being the Image.

 

Have a great one,

Sander


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