Ejemplo n.º 1
0
  def test_getRayDataArray(self):
    print("\nTEST: arraytrace.getRayDataArray()")
    
    # create RayData without any kwargs
    rd = at.getRayDataArray(numRays=5)
    self.assertEqual(len(rd), 6)
    self.assertEqual(rd[0].error, 5)     # number of rays
    self.assertEqual(rd[0].opd, 0)       # GetTrace ray tracing type
    self.assertEqual(rd[0].wave, 0)      # real ray tracing
    self.assertEqual(rd[0].want_opd,-1)  # last surface

    # create RayData with some more arguments
    rd = at.getRayDataArray(numRays=5, tType=3, mode=1, startSurf=2)
    self.assertEqual(rd[0].opd, 3)       # mode 3
    self.assertEqual(rd[0].wave,1)       # real ray tracing
    self.assertEqual(rd[0].vigcode,2)    # first surface

    # create RayData with kwargs
    rd = at.getRayDataArray(numRays=5, tType=2, x=1.0, y=1.0)
    self.assertEqual(rd[0].x,1.0)
    self.assertEqual(rd[0].y,1.0)
    self.assertEqual(rd[0].z,0.0)

    # create RayData with kwargs overriding some regular parameters
    rd = at.getRayDataArray(numRays=5, tType=2, x=1.0, y=1.0, error=1)
    self.assertEqual(len(rd),6)
    self.assertEqual(rd[0].x,1.0)
    self.assertEqual(rd[0].y,1.0)
    self.assertEqual(rd[0].z,0.0)
    self.assertEqual(rd[0].error,1)
Ejemplo n.º 2
0
def trace_rays():
    ln = pyz.createLink()
    filename = os.path.join(ln.zGetPath()[1], 'Sequential', 'Objectives', 
                            'Cooke 40 degree field.zmx')
    ln.zLoadFile(filename)
    print("Loaded zemax file:", ln.zGetFile())
    ln.zGetUpdate()   # In general this should be done ...
    if not ln.zPushLensPermission():
        print("\nERROR: Extensions not allowed to push lenses. Please enable in Zemax.")
        ln.close()
        sys.exit(0)
    ln.zPushLens(1)   # FOR SOME REASON, THE ARRAY RAY TRACING SEEMS TO
                      # BE WORKING ON THE LENS THAT IS IN THE MAIN ZEMAX APPLICATION WINDOW!!!!
    ln.zNewLens()     # THIS IS JUST TO PROVE THE ABOVE POINT!!! RAY TRACING STILL ON THE LENS
                      # IN THE MAIN ZEMAX APPLICATION, EVENTHOUGH THE LENS IN THE DDE SERVER IS A "NEW LENS"
    numRays = 101**2    # 10201
    rd = at.getRayDataArray(numRays, tType=0, mode=0, endSurf=-1)
    radius = int(sqrt(numRays)/2)

    # Fill the rest of the ray data array
    k = 0
    for i in xrange(-radius, radius + 1, 1):
        for j in xrange(-radius, radius + 1, 1):
            k += 1
            rd[k].z = i/(2*radius)                   # px
            rd[k].l = j/(2*radius)                   # py
            rd[k].intensity = 1.0
            rd[k].wave = 1

    # Trace the rays
    ret = at.zArrayTrace(rd, timeout=5000)

    # Dump the ray trace data into a file
    outputfile = os.path.join(cd, "arrayTraceOutput.txt")
    if ret==0:
        k = 0
        with open(outputfile, 'w') as f:
            f.write("Listing of Array trace data\n")
            f.write("     px      py error            xout            yout"
                    "         l         m         n    opd    Exr     Exi"
                    "     Eyr     Eyi     Ezr     Ezi    trans\n")
            for i in xrange(-radius, radius + 1, 1):
                for j in xrange(-radius, radius + 1, 1):
                    k += 1
                    line = ("{:7.3f} {:7.3f} {:5d} {:15.6E} {:15.6E} {:9.5f} "
                            "{:9.5f} {:9.5f} {:7.3f} {:7.3f} {:7.3f} {:7.3f} "
                            "{:7.3f} {:7.3f} {:7.3f} {:7.4f}\n"
                            .format(i/(2*radius), j/(2*radius), rd[k].error,
                                    rd[k].x, rd[k].y, rd[k].l, rd[k].m, rd[k].n,
                                    rd[k].opd, rd[k].Exr, rd[k].Exi, rd[k].Eyr,
                                    rd[k].Eyi, rd[k].Ezr, rd[k].Ezi, rd[k].intensity))
                    f.write(line)
        print("Success")
        print("Ray trace data outputted to the file {}".format(outputfile))
    else:
        print("There was some problem in ray tracing")

    ln.zNewLens()
    ln.zPushLens()
    ln.close()
def get_time_zArrayTrace(numRays, retRd=False):
    """return the time taken to perform ray tracing for the given number of rays
    using zArrayTrace() function.
    """
    radius = int(sqrt(numRays) / 2)
    startTime = time.clock()
    rd = at.getRayDataArray(numRays, tType=0, mode=0)
    # Fill the rest of the ray data array,
    # hx, hy are zeros; mode = 0 (real), surf =  img surf, waveNum = 1
    k = 0
    for i in xrange(-radius, radius + 1, 1):
        for j in xrange(-radius, radius + 1, 1):
            k += 1
            rd[k].z = i / (2 * radius)  # px
            rd[k].l = j / (2 * radius)  # py
            rd[k].intensity = 1.0
            rd[k].wave = 1
    # Trace the rays
    ret = at.zArrayTrace(rd, timeout=5000)
    endTime = time.clock()
    if ret == 0 and no_error_in_ray_trace(rd, numRays):
        if retRd:
            return (endTime - startTime) * 10e3, rd
        else:
            return (endTime - startTime) * 10e3  # time in milliseconds
Ejemplo n.º 4
0
def trace_rays():
    ln = pyz.createLink()
    filename = os.path.join(ln.zGetPath()[1], 'Sequential', 'Objectives', 
                            'Cooke 40 degree field.zmx')
    ln.zLoadFile(filename)
    print("Loaded zemax file:", ln.zGetFile())
    ln.zGetUpdate()   # In general this should be done ...
    if not ln.zPushLensPermission():
        print("\nERROR: Extensions not allowed to push lenses. Please enable in Zemax.")
        ln.close()
        sys.exit(0)
    ln.zPushLens(1)   # FOR SOME REASON, THE ARRAY RAY TRACING SEEMS TO
                      # BE WORKING ON THE LENS THAT IS IN THE MAIN ZEMAX APPLICATION WINDOW!!!!
    ln.zNewLens()     # THIS IS JUST TO PROVE THE ABOVE POINT!!! RAY TRACING STILL ON THE LENS
                      # IN THE MAIN ZEMAX APPLICATION, EVENTHOUGH THE LENS IN THE DDE SERVER IS A "NEW LENS"
    numRays = 101**2    # 10201
    rd = at.getRayDataArray(numRays, tType=0, mode=0, endSurf=-1)
    radius = int(sqrt(numRays)/2)

    # Fill the rest of the ray data array
    k = 0
    for i in range(-radius, radius + 1, 1):
        for j in range(-radius, radius + 1, 1):
            k += 1
            rd[k].z = i/(2*radius)                   # px
            rd[k].l = j/(2*radius)                   # py
            rd[k].intensity = 1.0
            rd[k].wave = 1

    # Trace the rays
    ret = at.zArrayTrace(rd, timeout=5000)

    # Dump the ray trace data into a file
    outputfile = os.path.join(cd, "arrayTraceOutput.txt")
    if ret==0:
        k = 0
        with open(outputfile, 'w') as f:
            f.write("Listing of Array trace data\n")
            f.write("     px      py error            xout            yout"
                    "         l         m         n    opd    Exr     Exi"
                    "     Eyr     Eyi     Ezr     Ezi    trans\n")
            for i in range(-radius, radius + 1, 1):
                for j in range(-radius, radius + 1, 1):
                    k += 1
                    line = ("{:7.3f} {:7.3f} {:5d} {:15.6E} {:15.6E} {:9.5f} "
                            "{:9.5f} {:9.5f} {:7.3f} {:7.3f} {:7.3f} {:7.3f} "
                            "{:7.3f} {:7.3f} {:7.3f} {:7.4f}\n"
                            .format(i/(2*radius), j/(2*radius), rd[k].error,
                                    rd[k].x, rd[k].y, rd[k].l, rd[k].m, rd[k].n,
                                    rd[k].opd, rd[k].Exr, rd[k].Exi, rd[k].Eyr,
                                    rd[k].Eyi, rd[k].Ezr, rd[k].Ezi, rd[k].intensity))
                    f.write(line)
        print("Success")
        print("Ray trace data outputted to the file {}".format(outputfile))
    else:
        print("There was some problem in ray tracing")

    ln.zNewLens()
    ln.zPushLens()
    ln.close()
def get_time_zArrayTrace(numRays, retRd=False):
    """return the time taken to perform ray tracing for the given number of rays
    using zArrayTrace() function.
    """
    radius = int(sqrt(numRays)/2)
    startTime = time.clock()
    rd = at.getRayDataArray(numRays, tType=0, mode=0)
    # Fill the rest of the ray data array,
    # hx, hy are zeros; mode = 0 (real), surf =  img surf, waveNum = 1
    k = 0
    for i in xrange(-radius, radius + 1, 1):
        for j in xrange(-radius, radius + 1, 1):
            k += 1
            rd[k].z = i/(2*radius)      # px
            rd[k].l = j/(2*radius)      # py
            rd[k].intensity = 1.0
            rd[k].wave = 1
    # Trace the rays
    ret = at.zArrayTrace(rd, timeout=5000)
    endTime = time.clock()
    if ret == 0 and no_error_in_ray_trace(rd, numRays):
        if retRd:
            return (endTime - startTime)*10e3, rd
        else:
            return (endTime - startTime)*10e3   # time in milliseconds
def spiralSpot_using_zArrayTrace(hx=0.0, hy=0.4, waveNum=1, spirals=10, numRays=600):
    """function replicates ``zSpiralSpot()`` using the ``pyzdde.arraytrace`` module 
    functions ``getRayDataArray()`` and ``zArrayTrace()``
    """
    startTime = time.clock()
    deltaTheta = (spirals*2.0*pi)/(numRays-1)
    # construct the ray data structure
    rd = at.getRayDataArray(numRays, tType=0, mode=0, endSurf=-1)
    for i in range(0, numRays):
        theta = i*deltaTheta
        r = i/(numRays-1)    
        px, py = r*cos(theta), r*sin(theta)
        rd[i+1].x = hx
        rd[i+1].y = hy
        rd[i+1].z = px
        rd[i+1].l = py
        rd[i+1].wave = waveNum
    # send ray data structure to Zemax for performing array tracing
    ret = at.zArrayTrace(rd)
    # retrieve the traced data from the ray data structure
    x, y = [0.0]*numRays, [0.0]*numRays
    if ret==0:                
        for i in range(1, numRays+1):
            x[i-1] = rd[i].x
            y[i-1] = rd[i].y
        endTime = time.clock()
        print("Execution time = {:4.2f}".format((endTime - startTime)*10e3), "ms")
        plotTracedData(x, y)
    else:
        print("Error in tracing rays")
Ejemplo n.º 7
0
  def test_cross_check_zArrayTrace_vs_zGetTraceNumpy_OLD(self):
    print("\nTEST: comparison of zArrayTrace and zGetTraceNumpy OLD")
    # Load a lens file into the LDE
    filename = get_test_file()
    self.ln.zLoadFile(filename)
    self.ln.zPushLens(1);  
    # set-up field and pupil sampling
    nr = 22;
    rd = at.getRayDataArray(nr)
    hx,hy,px,py = 2*np.random.rand(4,nr)-1;
    
    for k in range(nr):
      rd[k+1].x = hx[k];
      rd[k+1].y = hy[k];
      rd[k+1].z = px[k];
      rd[k+1].l = py[k];
      rd[k+1].intensity = 1.0;
      rd[k+1].wave = 1;
      rd[k+1].want_opd = 0;
    # results of zArrayTrace  
    ret = at.zArrayTrace(rd);
    self.assertEqual(ret,0);
    results = np.asarray( [[r.error,r.vigcode,r.x,r.y,r.z,r.l,r.m,r.n,\
                             r.Exr,r.Eyr,r.Ezr,r.opd,r.intensity] for r in rd[1:]] );
    # results of GetTraceArray
    (error,vigcode,pos,dir,normal,intensity) = \
        nt.zGetTraceArray(hx,hy,px,py,bParaxial=0);

    # compare
    self.assertTrue(np.array_equal(error,results[:,0]),msg="error differs");    
    self.assertTrue(np.array_equal(vigcode,results[:,1]),msg="vigcode differs");    
    self.assertTrue(np.array_equal(pos,results[:,2:5]),msg="pos differs");    
    self.assertTrue(np.array_equal(dir,results[:,5:8]),msg="dir differs");    
    self.assertTrue(np.array_equal(normal,results[:,8:11]),msg="normal differs");    
    self.assertTrue(np.array_equal(intensity,results[:,12]),msg="intensity differs");       
def spiralSpot_using_zArrayTrace(hx=0.0,
                                 hy=0.4,
                                 waveNum=1,
                                 spirals=10,
                                 numRays=600):
    """function replicates ``zSpiralSpot()`` using the ``pyzdde.arraytrace`` module 
    functions ``getRayDataArray()`` and ``zArrayTrace()``
    """
    startTime = time.clock()
    deltaTheta = (spirals * 2.0 * pi) / (numRays - 1)
    # construct the ray data structure
    rd = at.getRayDataArray(numRays, tType=0, mode=0, endSurf=-1)
    for i in range(0, numRays):
        theta = i * deltaTheta
        r = i / (numRays - 1)
        px, py = r * cos(theta), r * sin(theta)
        rd[i + 1].x = hx
        rd[i + 1].y = hy
        rd[i + 1].z = px
        rd[i + 1].l = py
        rd[i + 1].wave = waveNum
    # send ray data structure to Zemax for performing array tracing
    ret = at.zArrayTrace(rd)
    # retrieve the traced data from the ray data structure
    x, y = [0.0] * numRays, [0.0] * numRays
    if ret == 0:
        for i in range(1, numRays + 1):
            x[i - 1] = rd[i].x
            y[i - 1] = rd[i].y
        endTime = time.clock()
        print(
            "Execution time (zArrayTrace) = {:4.2f}".format(
                (endTime - startTime) * 10e3), "ms")
        plotTracedData(x, y)
    else:
        print("Error in tracing rays")
Ejemplo n.º 9
0
    def trace_rays(self, x, y, px, py, waveNum, mode=0, surf=-1):
        """ 
    array trace of rays
    
    Parameters
    ----------
      x,y : vectors of length nRays
        reduced field coordinates for each ray (normalized between -1 and 1)
      px,py : vectors of length nRays
        reduced pupil coordinates for each ray (normalized between -1 and 1)
      waveNum : integer
        wavelength number
      mode : integer, optional
        0= real (default), 1 = paraxial
      surf : integer, optional
        surface to trace the ray to. Usually, the ray data is only needed at
        the image surface (``surf = -1``, default)

    Returns
    --------
      numpy array of shape (nRays,8) containing following parameters for each ray
      
      err : error flag
        * 0 = ray traced successfully;
        * +ve number = the ray missed the surface;
        * -ve number = the ray total internal reflected (TIR) at surface given 
          by the absolute value of the ``error``
      vigcode : integer
        The first surface where the ray was vignetted. Raytrace is continued.       
      x,y,z : float 
        cartesian coordinates of ray on requested surface (local coordinates)
      l,m,n : float 
        direction cosines after requested surface (local coordinates)
      l2,m2,n2 : float
        direction cosines of surface normal at point of incidence (local coordinates)
       
    """
        # enlarge all vector arguments to same size
        nRays = max(map(np.size, (x, y, px, py, waveNum)))
        if np.isscalar(x): x = np.zeros(nRays) + x
        if np.isscalar(y): y = np.zeros(nRays) + y
        if np.isscalar(px): px = np.zeros(nRays) + px
        if np.isscalar(py): py = np.zeros(nRays) + py
        if np.isscalar(waveNum): waveNum = np.zeros(nRays, np.int) + waveNum
        assert (all(args.size == nRays for args in [x, y, px, py, waveNum]))
        print("number of rays: %d" % nRays)
        import time
        t = time.time()

        # fill in ray data array (following Zemax notation!)
        rays = at.getRayDataArray(nRays, tType=0, mode=mode, endSurf=surf)
        for k in range(nRays):
            rays[k + 1].x = x[k]
            rays[k + 1].y = y[k]
            rays[k + 1].z = px[k]
            rays[k + 1].l = py[k]
            rays[k + 1].wave = waveNum[k]

        print("set pupil values: %ds" % (time.time() - t))

        # Trace the rays
        ret = at.zArrayTrace(rays, timeout=100000)
        print(("zArrayTrace: %ds" % (time.time() - t)))

        # collect results
        results = np.asarray([(r.error, r.vigcode, r.x, r.y, r.z, r.l, r.m,
                               r.n, r.Exr, r.Eyr, r.Ezr) for r in rays[1:]])
        print(("retrive data: %ds" % (time.time() - t)))
        return results
Ejemplo n.º 10
0
  def trace_rays(self,x,y, px,py, waveNum, mode=0, surf=-1):
    """ 
    array trace of rays
    
    Parameters
    ----------
      x,y : vectors of length nRays
        reduced field coordinates for each ray (normalized between -1 and 1)
      px,py : vectors of length nRays
        reduced pupil coordinates for each ray (normalized between -1 and 1)
      waveNum : integer
        wavelength number
      mode : integer, optional
        0= real (default), 1 = paraxial
      surf : integer, optional
        surface to trace the ray to. Usually, the ray data is only needed at
        the image surface (``surf = -1``, default)

    Returns
    --------
      numpy array of shape (nRays,8) containing following parameters for each ray
      
      err : error flag
        * 0 = ray traced successfully;
        * +ve number = the ray missed the surface;
        * -ve number = the ray total internal reflected (TIR) at surface given 
          by the absolute value of the ``error``
      vigcode : integer
        The first surface where the ray was vignetted. Raytrace is continued.       
      x,y,z : float 
        cartesian coordinates of ray on requested surface (local coordinates)
      l,m,n : float 
        direction cosines after requested surface (local coordinates)
      l2,m2,n2 : float
        direction cosines of surface normal at point of incidence (local coordinates)
       
    """
    # enlarge all vector arguments to same size    
    nRays = max(map(np.size,(x,y,px,py,waveNum)));
    if np.isscalar(x): x = np.zeros(nRays)+x;
    if np.isscalar(y): y = np.zeros(nRays)+y;
    if np.isscalar(px): px = np.zeros(nRays)+px;
    if np.isscalar(py): py = np.zeros(nRays)+py;    
    if np.isscalar(waveNum): waveNum=np.zeros(nRays,np.int)+waveNum;
    assert(all(args.size == nRays for args in [x,y,px,py,waveNum]))
    print("number of rays: %d"%nRays);
    import time;  t = time.time();    
        
    # fill in ray data array (following Zemax notation!)
    rays = at.getRayDataArray(nRays, tType=0, mode=mode, endSurf=surf)
    for k in range(nRays):
      rays[k+1].x = x[k]      
      rays[k+1].y = y[k]
      rays[k+1].z = px[k]
      rays[k+1].l = py[k]
      rays[k+1].wave = waveNum[k];

    print("set pupil values: %ds"%(time.time()-t))

    # Trace the rays
    ret = at.zArrayTrace(rays, timeout=100000);
    print(("zArrayTrace: %ds"%(time.time()-t)))

    # collect results
    results = np.asarray( [(r.error,r.vigcode,r.x,r.y,r.z,r.l,r.m,r.n,r.Exr,r.Eyr,r.Ezr) for r in rays[1:]] );
    print(("retrive data: %ds"%(time.time()-t)))    
    return results;