xzos/PyZDDE

Helper function ``zGetTraceArray()`` for array ray tracing fails in Python 3

indranilsinharoy opened this issue · 0 comments

Calling the function zGetTraceArray() in Python 3 causes the function to fail, which doesn't happen in Python 2.7x. For example, consider the following code snippet:

r = np.linspace(0, 1, numRays)
theta = np.linspace(0, spirals*2.0*pi, numRays)
px = (r*np.cos(theta)).tolist()
py = (r*np.sin(theta)).tolist()
# trace the rays
tData = at.zGetTraceArray(numRays, [hx]*numRays, [hy]*numRays, px, py, waveNum=waveNum)
# parse traced data and plot 
err, _, x, y, _, _, _, _, _, _, _, _, _ = tData

Executing the above in Python 3, fails and produces the following traceback:

File "...\PyZDDE\pyzdde\arraytrace.py", line 274, in zGetTraceArray
    x[i-1] = rd[i].x
NameError: global name 'x' is not defined
Exception TypeError: 'unorderable types: int() <= NoneType()' in <bound method PyZDDE.__del__ of PyZDDE(appName='ZEMAX', appNum=1, connection=True, macroPath=None)> ignored

This happens because there is a change in how exec() behaves in Python 2 vs Python 3.

In Python 3 executing

...
reals = ['x', 'y', 'z', 'l', 'm', 'n', 'l2', 'm2', 'n2', 'opd', 'intensity']
ints = ['error', 'vigcode']
for r in reals:
    exec(r + " = [0.0] * numRays")
for i in ints:
    exec(i + " = [0] * numRays")
...

creates the names x, y, etc. in the local namespace, but the Python interpreter searches for these variables in the global namespace [SO question]