Solved

Batch Ray Trace: adapt "toSurface" in loop

  • 2 October 2023
  • 2 replies
  • 40 views

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")

 

icon

Best answer by David.Nguyen 2 October 2023, 18:23

View original

2 replies

Userlevel 7
Badge +2

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

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