Hello again,
I noticed that I can use OpenBatchRayTrace instead of calling the standard non-sequential ray tracing routine from python.
The only thing that I need to do is to use a CreateNSC interface which returns a TraceNSCData object. Then I can apply the same procedure as with the batch based ray-tracing approach for sequential systems.
Of course there are a few differences, with the most important one being the fact that in non-sequential mode there is no concept of pupil and field coordinates. Instead I need to define the X,Y,Z and L,M,N vectors associated to the rays I want to trace through the nonsequential system.
In general, I think this works (please let me know if there is something that I might be missing?), however, I noticed that I have to be pulling the results ray by ray (even though the tracing is all done in a batch).
I was wondering if there could be a better way to retrieve the results without having to go ray by ray and instead pull all of the results related to a specific segment of the non-sequential tracing sequence?
Also, as I mentioned in my first post, the results obtained from NSCData.ReadNextSegment() do not provide information on the surface normal at the intersection points. I could obtain the surface normal information from the retrieved L,M,N vectors for each ray at each interface. However, just to be clear, these L,M,N vectors are expressed in the global coordinate system basis right ?(the L,M,N vectors before and after an interface). If this is the case I would obtain the surface normals (also expressed in global coordinates) by using Snell’s law in vector form. What do you think about this?
Here is a copy of the code that I am using at the moment (ZOS-API via python)
zos = PythonStandaloneApplication()
# Load local variables
ZOSAPI = zos.ZOSAPI
TheApplication = zos.TheApplication
TheSystem = zos.TheSystem
TheSystem.LoadFile(path, False)
print ("number of surfaces")
print (TheSystem.LDE.NumberOfSurfaces)
raytrace = TheSystem.Tools.OpenBatchRayTrace()
sysInt = Int32(1)
sysDbl = Double(1.0)
sysDbl2 = Double(0.0)
Nx = 100
Ny = 100
nrays = Nx*Ny
NSCData = raytrace.CreateNSC(Nx*Ny,5,0)
NSCData.ClearData()
theta = np.linspace(0,np.deg2rad(60.0),Nx)
phi = np.linspace(0,np.deg2rad(360.0),Ny)
thetat, phip = np.meshgrid(theta, phi)
l = np.sin(thetat)*np.cos(phip)
m = np.sin(thetat)*np.sin(phip)
n = np.cos(thetat)
l = l.flatten()
m = m.flatten()
n = n.flatten()
for i in range(0,l.shapes0],1):
NSCData.AddRay(sysInt,1,Enum.Parse(ZOSAPI.Tools.RayTrace.NSCTraceOptions,"None"),Double(0.0),Double(0.0),Double(0.0),l.i],m[i],n[i],sysInt,0.0,0.0,sysDbl2,sysDbl2,sysDbl2,sysDbl2)
print ("How many rays we have??")
print (NSCData.NumberOfRays)
raytrace.RunAndWaitForCompletion()
print ("Non sequential ray tracing completed")
NSCData.StartReadingResults()
x_coordinates = np.empty((nrays,5))
y_coordinates = np.empty((nrays,5))
z_coordinates = np.empty((nrays,5))
results2 = NSCData.ReadNextResult(1,sysInt,sysInt,sysInt)
while results2u0]:
# print ("Results for ray number: {}".format(results2u1]))
# print (results2)
results = NSCData.ReadNextSegment()
# print ("Results associated to ray number:{}".format(results2u1]))
while resultss0]: # success
# print ("These are the results")
# print (results)
x_coordinatesnresults2u1]-1,resultss1]] = resultss5]
y_coordinatesnresults2u1] - 1, resultss1]] = resultss6]
z_coordinatesnresults2u1] - 1, resultss1]] = resultss7]
results = NSCData.ReadNextSegment()
results2 = NSCData.ReadNextResult(1,sysInt,sysInt,sysInt)
print ("This worked")
print ("type of NSCData")
print (type(NSCData))
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.scatter(x_coordinatesn:,4],y_coordinatesn:,4],z_coordinatesn:,4])
plt.title("Ray intersection with first surface")
plt.show()
raytrace.Close()
del zos
zos = None
Any comments or thoughts?