Example #1
0
    def runTest(self):
        z = Connection()
        z.NewLens()
        model = SurfaceSequence(z, empty=True)
        build_coord_break_sequence(model)

        # set each surface to be the global reference, in turn
        last = None
        for surf in model:
            surf.make_global_reference()
            self.assertTrue(surf.is_global_reference)
            if last is not None:
                self.assertFalse(last.is_global_reference)
            rot, offset = z.GetGlobalMatrix(surf.get_surf_num())
            self.assertAlmostEqual(abs(rot - numpy.eye(3)).max(), 0)
            self.assertAlmostEqual(abs(offset).max(), 0)
            last = surf
Example #2
0
class RayCoordinates(unittest.TestCase):
    marginal_ray_solve_pupil_coordinate = 0.7
    tracing_accuracy = 4  # expected accuracy in decimal places

    def setUp(self):
        self.z = Connection()
        self.z.NewLens()
        self.model = SurfaceSequence(self.z)
        self.system = SystemConfig(self.z)
        self.system.rayaimingtype = 0

        self.model[0].thickness = 10.0

        # insert fold mirror
        self.model.append_new(surface.CoordinateBreak, rotate_y=40.0,
                              rotate_z=10.0)
        self.model.append_new(surface.Standard, glass="MIRROR")
        cb = self.model.append_new(surface.CoordinateBreak, thickness=-20.0)
        cb.rotate_x.align_to_chief_ray()
        cb.rotate_y.align_to_chief_ray()

        front = self.model.append_new(surface.Standard,
                                      curvature=-0.05, glass="BK7",
                                      thickness=-1.0)
        back = self.model.append_new(surface.Standard,
                                     curvature=-front.curvature.linked())

        self.z.SetSystemAper(3, front.get_surf_num(), 2.5)
        back.thickness.focus_on_next(self.marginal_ray_solve_pupil_coordinate)

        self.z.GetUpdate()

    def testFocus(self):
        image = self.model[-1]
        chief = image.get_ray_intersect()
        marginal = image.get_ray_intersect(
            (0, 0), (0, self.marginal_ray_solve_pupil_coordinate), 0)
        self.assertAlmostEqual(abs(marginal.intersect - chief.intersect).max(),
                               0.0)

    def testDirectTracing(self):
        """Verify that we can launch rays using normalised pupil coordinates and local
        surface cartesian coordinates, with consistent results."""

        pc = (0.3, 0.5)  # normalised pupil coordinate under test
        image = self.model[-1]
        # find ray intersection on image plane
        (status, vigcode, im_intersect, im_exit_cosines, normal,
         intensity) = image.get_ray_intersect((0, 0), pc)
        for surf in self.model:
            # get ray intersection on surface
            (status, vigcode, surf_intersect, exit_cosines, normal,
             intensity) = surf.get_ray_intersect((0, 0), pc)

            # Launch ray directly using the obtained origin and exit cosines.
            # GetTraceDirect launches a ray from startsurf coordinate
            # frame, but the ray does not interact with startsurf.

            (status, vigcode, intersect, cosines, normal,
             intensity) = self.z.GetTraceDirect(0, 0,
                                                surf.get_surf_num(),
                                                image.get_surf_num(),
                                                surf_intersect,
                                                exit_cosines)

            # verify that the ray is the same as obtained with
            # normalised pupil coordinates on the image plane
            self.assertAlmostEqual(abs(intersect - im_intersect).max(), 0.0,
                                   self.tracing_accuracy)
            self.assertAlmostEqual(abs(cosines - im_exit_cosines).max(), 0.0,
                                   self.tracing_accuracy)
            if surf.id != image.id:
                self.assertNotAlmostEqual(
                    abs(surf_intersect - im_intersect).max(),
                    0.0, self.tracing_accuracy)

    def testMatrixCoordinateTransforms(self):
        """Check we can acquire and use global transformation matrices.

        Make each surface the coordinate global reference in turn.
        For each iteration check we can recover the original global
        reference of each surface by applying the inverse of the new
        global reference."""

        def trans_mat(rotation, offset):
            m = numpy.zeros((4, 4), float)
            m[0:3, 0:3] = rotation
            m[0:3, 3] = offset
            m[3, 3] = 1.0
            return numpy.matrix(m)

        surf_ids = range(len(self.model))
        initial_global_ref = self.system.globalrefsurf
        initial_surface_coord_frames = [
            trans_mat(*self.z.GetGlobalMatrix(i)) for i in surf_ids]

        for i in surf_ids:
            if isinstance(self.model[i], surface.CoordinateBreak):
                # coordinate breaks as global reference surfaces give
                # unexpected results
                continue

            self.system.globalrefsurf = i
            # find inverse transformation
            trans = initial_surface_coord_frames[i].I

            self.z.GetUpdate()
            for j in surf_ids:
                new_frame = trans_mat(*self.z.GetGlobalMatrix(j))
                # calc_frame = numpy.dot(trans,
                #     initial_surface_coord_frames[j])
                calc_frame = trans * initial_surface_coord_frames[j]
                self.assertAlmostEqual(abs(new_frame - calc_frame).max(), 0)

    def testCheckRayTraceResults(self):
        pc = (0.3, 0.5)  # normalised pupil coordinate under test
        for surf in self.model:
            n = surf.get_surf_num()
            # get ray intersection on surface in local coordinates
            # (status, vigcode, intersect, exit_cosines, normal,
            # intensity) = surf.get_ray_intersect((0,0), pc)
            ray = surf.get_ray_intersect((0, 0), pc)
            # compare with values obtained from operands
            for val, op in zip(ray.intersect, ("REAX", "REAY", "REAZ")):
                opval = self.z.OperandValue(op, n, 0, 0.0, 0.0, pc[0], pc[1])
                self.assertAlmostEqual(opval, val, places=5)

            # get ray intersection on surface in global coordinates
            # (status, vigcode, intersect_gl, exit_cosines, normal,
            # intensity) = surf.get_ray_intersect((0,0), pc, _global=True)
            glray = surf.get_ray_intersect((0, 0), pc, _global=True)
            # compare with direct global coordinates from operands
            for val, op in zip(glray.intersect, ("RAGX", "RAGY", "RAGZ")):
                opval = self.z.OperandValue(op, n, 0, 0.0, 0.0, pc[0], pc[1])
                self.assertAlmostEqual(opval, val, self.tracing_accuracy)
Example #3
0
class CoordinateReturn(unittest.TestCase):
    def setUp(self):
        self.z = Connection()
        self.z.NewLens()
        self.model = SurfaceSequence(self.z, empty=True)
        self.first, self.last = build_coord_break_sequence(self.model)

    def testZemaxCoordinateReturn(self):
        cb = self.model.append_new(surface.CoordinateBreak)
        return_surf = cb.get_surf_num()
        self.z.SetSurfaceData(return_surf, 81, self.first)
        self.z.SetSurfaceData(return_surf, 80, 3)  # orientation + offset
        self.z.GetUpdate()
        self.coord_return_common_tests(return_surf)

    def testLibraryCoordinateReturn(self):
        cb = self.model.append_new(surface.CoordinateBreak)
        cb.return_to(self.model[self.first])
        self.z.GetUpdate()
        self.coord_return_common_tests(cb.get_surf_num())
        # To unset the coordinate return, pass None (has no effect here)
        cb.return_to(None)  # unset coordinate return status

    def testFull(self):
        return_surf = return_to_coordinate_frame(self.model, self.first,
                                                 self.last)
        self.z.GetUpdate()
        self.coord_return_common_tests(return_surf)

    def testOmitZeroThicknesses(self):
        self.z.GetUpdate()
        return_surf = return_to_coordinate_frame(self.model,
                                                 self.first,
                                                 self.last,
                                                 include_null_transforms=False)
        self.z.GetUpdate()
        self.coord_return_common_tests(return_surf)

    def testWithCursor(self):
        insert_point = self.last
        insertion_point_sequence = count(insert_point+1)

        def factory():
            return self.model.insert_new(next(insertion_point_sequence),
                                         surface.CoordinateBreak)

        self.z.GetUpdate()
        return_surf = return_to_coordinate_frame(self.model,
                                                 self.first,
                                                 self.last,
                                                 include_null_transforms=False,
                                                 factory=factory)
        self.z.GetUpdate()
        self.coord_return_common_tests(return_surf)

    def testWithAppend(self):
        def factory():
            return self.model.append_new(surface.CoordinateBreak)
        self.z.GetUpdate()
        return_surf = return_to_coordinate_frame(self.model,
                                                 self.first,
                                                 self.last,
                                                 include_null_transforms=False,
                                                 factory=factory)
        self.z.GetUpdate()
        self.coord_return_common_tests(return_surf)

    def coord_return_common_tests(self, return_surf):
        first_rot, first_offset = self.z.GetGlobalMatrix(self.first)
        last_rot, last_offset = self.z.GetGlobalMatrix(self.last)
        return_rot, return_offset = self.z.GetGlobalMatrix(return_surf + 1)

        # check coordinate frames are identical
        self.assertAlmostEqual(abs(first_rot - return_rot).max(), 0)
        self.assertAlmostEqual(abs(first_offset - return_offset).max(), 0)

        # check we have finite rotation matrices
        self.assertNotAlmostEqual(abs(first_rot).max(), 0)

        # check that first and last frames differ
        self.assertNotAlmostEqual(abs(first_rot - last_rot).max(), 0)
        self.assertNotAlmostEqual(abs(first_offset - last_offset).max(), 0)