예제 #1
0
def test_conic_surface():
    # Prove that with a conic surface we can focus parallel rays perfectly.
    n1 = 1
    n2 = 1.5
    f = 1
    roc = f * (n2 - n1) / n2
    x0s = [-0.2, -0.1, 0, 0.1, 0.2]
    # There is a formula for this:
    # https://www.iap.uni - jena.de/iapmedia/de/Lecture/Advanced + Lens + Design1393542000/ALD13_Advanced + Lens + Design + 7 + _ + Aspheres + and +freeforms.pdf
    # but I obtained it numerically (in demo_conic_surface.py).
    kappa = 0.55555
    f = roc * n2 / (n2 - n1)
    interface = rt1.FresnelInterface(ri.FixedIndex(n1), ri.FixedIndex(n2))
    conic_surface = rt1.Surface(rt1.ConicProfile(roc, kappa),
                                interface=interface)
    origin = v4hb.stack_xyzw(x0s, 0, -1, 1)
    vector = v4hb.stack_xyzw(0, 0, 1, 0)
    detector_surface = rt1.Surface(rt1.PlanarProfile(),
                                   matrix=h4t.make_translation(0, 0, f))
    surfaces = conic_surface, detector_surface
    line = rt1.Line(origin, vector)
    pol = v4hb.cross(line.vector, [0, 1, 0, 0])
    ray = rt1.Ray(line, pol, 1, 0, 860e-9, n1)
    segments = ray.trace_surfaces(surfaces, ['transmitted', 'incident'])[0]
    assert len(segments) == 3
    xy = segments[-1].ray.line.origin[..., :2]
    # The focusing is close (f number 2.5) but not quite perfect due to errors in the intersection solver.
    assert np.allclose(xy, 0, atol=2e-6)
예제 #2
0
def test_tracing():
    normal = v4h.to_vector((0, 0, -1))
    constant = 0
    surface = sdb.Plane(normal, constant)
    n0 = 1
    n0fun = ri.FixedIndex(n0)
    n1  = 1.5
    n1fun = ri.FixedIndex(n1)
    element = rt2.Element(surface, rt2.UniformIsotropic(n1fun), rt2.FresnelInterface())

    #assert rt2.get_deflector(element, np.asarray((1, 2, 3, 1))) is deflector

    assembly = rt2.Assembly(element.surface, [element], rt2.UniformIsotropic(n0fun))
    assert _get_transformed_element(assembly, v4h.to_point((1, 2, -1))) is None
    affine_surface = _get_transformed_element(assembly, v4h.to_point((1, 2, 1))).surface

    lamb = 800e-9
    incident_ray = rt2.make_ray(assembly, 1., 2, -1, 0, 1, 1, 1, 0, 0, lamb)
    epsilon = 1e-9
    length, deflected_rays = _process_ray(assembly, incident_ray, dict(epsilon=epsilon, t_max=1e9, max_steps=100))
    assert (2**0.5 - epsilon) <= length  <= (2**0.5 + epsilon)

    (rp, rs), (tp, ts) = functions.calc_fresnel_coefficients(n0, n1, abs(dot(incident_ray.line.vector, normal)))
    assert 0 <= npscalar.getsdb(surface, deflected_rays[0].line.origin) <= epsilon
    assert np.array_equal(deflected_rays[0].line.vector, normalize(v4h.to_vector((0, 1, -1, 0))))
    assert np.isclose(deflected_rays[0].flux, rs**2)

    vy = 2**-0.5*n0/n1
    assert 0 >= npscalar.getsdb(surface, deflected_rays[1].line.origin) >= -epsilon
    assert np.allclose(deflected_rays[1].line.vector, (0, vy, (1 - vy**2)**0.5, 0))
    assert np.isclose(deflected_rays[1].flux, ts**2*n1/n0)
예제 #3
0
def test_Train_make_singlet():
    n = 3
    f = 10
    shapes = np.asarray((-1, 0, 1))
    d = 0.1
    for ne in (1, 1.5):
        for shape in shapes:
            train = trains.Train.design_singlet(ri.FixedIndex(n),
                                                f,
                                                shape,
                                                d,
                                                0.01,
                                                ne=ri.FixedIndex(ne))
            assert np.allclose(train.get_focal_lengths() / ne, f)
예제 #4
0
파일: test_sbt.py 프로젝트: draustin/otk
def test_beam_tracing(qtbot):
    n = 1.5
    lamb = 860e-9
    w = 80e-3
    f = 100e-3
    waist = 20e-6
    k = 2*np.pi/lamb
    roc, center_thickness = paraxial.design_thick_spherical_transform_lens(n, w, f)
    lens_surfaces = rt1.make_spherical_lens_surfaces(roc, -roc, center_thickness, ri.FixedIndex(n))
    z_fp = center_thickness/2 + w
    beam = asbt1.Beam(asbp.PlaneProfile.make_gaussian(lamb, 1, waist, 160e-6, 64, z_waist=-z_fp))
    surface1 = rt1.Surface(rt1.PlanarProfile(), otk.h4t.make_translation(0, 0, z_fp))
    surfaces = lens_surfaces + (surface1,)
    beam_segments = asbt1.trace_surfaces(beam, surfaces, ['transmitted', 'transmitted', None])

    origin = beam.to_global(v4hb.stack_xyzw([0, -waist, waist, 0, 0], [0, 0, 0, -waist, waist], -z_fp, 1))
    vector_local = v4hb.normalize(v4hb.stack_xyzw([0, 2/waist, -2/waist, 0, 0], [0, 0, 0, 2/waist, -2/waist], k, 0))
    vector = beam.to_global(vector_local)
    line = otk.rt1._lines.Line(origin, vector)
    polarization = v4hb.normalize(v4hb.cross(vector, [1,0,0,0]))
    ray_segments = otk.rt1._raytrace.Ray(line, polarization, 1, 0, lamb, 1).trace_surfaces(surfaces, ['transmitted', 'transmitted', 'incident'])

    # TODO resurrect
    # segments = [asbp.BeamRaySegment.combine(bs, rs) for bs, rs in zip(beam_segments, ray_segments)]
    #
    # widget = asbp.MultiProfileWidget.plot_segments(segments)
    # qtbot.addWidget(widget)
    # for n in range(len(widget.entries)):
    #     widget.set_index(n)
예제 #5
0
def test_refraction():
    """Test collimation of a point source by a spherical refracting surface."""
    n1 = 1.5
    n2 = 3
    f = 100
    r0 = np.asarray((100, 20, 300, 1))
    interface = rt1.FresnelInterface(ri.FixedIndex(n1), ri.FixedIndex(n2))
    s = rt1.Surface(rt1.SphericalProfile(f * (n2 - n1)),
                    otk.h4t.make_translation(*r0[:3]),
                    interface=interface)
    origin = r0 + (0, 0, -f * n1, 0)
    line = rt1.Line(origin, v4hb.normalize((0.001, 0.001, 1, 0)))
    pol = v4hb.cross(line.vector, [0, 1, 0, 0])
    ray = rt1.Ray(line, pol, 0, 860e-9, n1)
    segments = ray.trace_surfaces((s, ), ('transmitted', ))[0]
    assert len(segments) == 2
    assert segments[-1].ray.n == n2
    assert np.allclose(segments[-1].ray.line.vector, (0, 0, 1, 0))
예제 #6
0
def test_Train_make_singlet_transform2():
    n = 1.5
    f = 10
    shapes = np.asarray((-1, 0, 1))
    d = 0.1
    for shape in shapes:
        train = trains.Train.make_singlet_transform2(ri.FixedIndex(n), f,
                                                     shape, d, 0.01)
        assert np.allclose(train.get_focal_lengths(), f)
예제 #7
0
def test_make_square_element_train():
    index = ri.FixedIndex(1.5)
    train = trains.Singlet.from_focal_length(100e-3, index, 5e-3, 12.5e-3, 0)
    element = rt2.to_rectangular_array_element(
        train, [sdb.RectangularArrayLevel.make(12.5e-3, 3)], (1, 2, 3))

    assert element.medium == rt2.UniformIsotropic(index)
    front = element.surface.surfaces[0]
    assert front.sagfun.unit.roc == train.surfaces[0].roc
예제 #8
0
def test_Train_principal_planes():
    n = 1.5
    f = 0.5
    shape = 0.1
    thickness = 0.01
    l = trains.Train.design_singlet(ri.FixedIndex(n), f, shape, thickness,
                                    0.01)
    ppb, ppf = l.get_principal_planes()
    _, ppb_, ppf_ = paraxial.calc_thick_spherical_lens(n, l.interfaces[0].roc,
                                                       l.interfaces[1].roc,
                                                       thickness)
    assert np.isclose(ppb, ppb_)
    assert np.isclose(ppf, ppf_)
예제 #9
0
def test_Train_make_singlet_transform1():
    n = 1.5
    ws = 1, 2
    f = 10
    l = trains.Train.make_singlet_transform1(ri.FixedIndex(n), ws, f, 0.01)
    testing.assert_allclose(l.get_focal_lengths(), (f, f))
    assert len(l.spaces) == 3
    assert np.isclose(l.spaces[0], ws[0])
    assert np.isclose(l.spaces[2], ws[1])
    testing.assert_allclose(l.get_focal_lengths(), (f, f))

    l2 = l.pad_to_transform()
    testing.assert_allclose(l2.get_working_distances(), (0, 0), atol=2e-15)
예제 #10
0
def test_hyperbolic_lens():
    # Prove that with a conic surface we can focus parallel rays perfectly.
    n1 = 1
    n2 = 1.5
    f = 1
    roc = f*(n2 - n1)/n2
    x0s = [-0.2, -0.1, 0., 0.1, 0.2]
    # There is a formula for this:
    # https://www.iap.uni - jena.de/iapmedia/de/Lecture/Advanced + Lens + Design1393542000/ALD13_Advanced + Lens + Design + 7 + _ + Aspheres + and +freeforms.pdf
    # but I obtained it numerically (in demo_conic_surface.py).
    kappa = 0.55555 # 0.55555
    f = roc*n2/(n2 - n1)
    surface = sdb.ZemaxConic(roc, 0.3, 1, kappa)
    element = rt2.Element(surface, rt2.UniformIsotropic(ri.FixedIndex(n2)), rt2.perfect_refractor)
    assembly = rt2.Assembly(surface, [element], rt2.UniformIsotropic(ri.FixedIndex(n1)))
    sphere_trace_kwargs = dict(epsilon=1e-9, t_max=1e9, max_steps=100)
    focus = (0, 0, f, 1)
    for x0 in x0s:
        ray = rt2.make_ray(assembly, x0, 0, -1, 0, 0, 1, 1, 0, 0, 800e-9)
        segments = rt2.nonseq_trace(assembly, ray, sphere_trace_kwargs).flatten()
        assert len(segments) == 2
        assert norm(segments[1].ray.line.pass_point(focus)[1].origin - focus) < 1e-6
예제 #11
0
def test_make_spherical_lens_surfaces():
    roc1 = 100
    roc2 = 50
    d = 30
    n = 1.5
    f, h1, h2 = paraxial.calc_thick_spherical_lens(n, roc1, -roc2, d)
    surfaces = rt1.make_spherical_lens_surfaces(roc1, -roc2, d,
                                                ri.FixedIndex(n))
    line = rt1.Line((0, 0, -f + h1 - d / 2, 1),
                    v4hb.normalize((1e-4, 1e-4, 1, 0)))
    pol = v4hb.cross(line.vector, [0, 1, 0, 0])
    ray = rt1.Ray(line, pol, 0, 860e-9, 1)
    segments = ray.trace_surfaces(surfaces, ['transmitted'] * 2)[0]
    assert len(segments) == 3
    assert segments[1].ray.n == n
    assert np.allclose(segments[-1].ray.line.vector, (0, 0, 1, 0))
예제 #12
0
def test_Interface_calc_mask():
    n1 = ri.vacuum
    n2 = ri.FixedIndex(1.5)
    roc = 0.1
    lamb = 530e-9
    rho = 0.05
    interface = trains.Interface(n1, n2, roc, 10e-3)
    f, gradf = interface.calc_mask(lamb, rho, True)

    sag = functions.calc_sphere_sag(roc, rho)
    k = 2 * np.pi / lamb
    deltan = n1(lamb) - n2(lamb)
    assert np.isclose(f, np.exp(1j * sag * k * deltan))

    grad_sag = functions.calc_sphere_sag(roc, rho, True)
    assert np.isclose(gradf, 1j * k * deltan * grad_sag * f)
예제 #13
0
    def propagate(self):
        lamb = self.wavelength_widget.value() * 1e-9
        waist0 = self.source_diameter_widget.value() / 2 * 1e-3
        num_points = self.num_points
        rs_waist = np.asarray((self.source_x_widget.value() * 1e-3,
                               self.source_y_widget.value() * 1e-3))
        source_z = self.source_z_widget.value() * 1e-3
        roc1 = self.roc1_widget.value() * 1e-3
        roc2 = self.roc2_widget.value() * 1e-3
        d = self.thickness_widget.value() * 1e-3
        n = ri.FixedIndex(self.n_widget.value())
        # These are calculated by lens update.
        f = self.f
        w1 = self.w1
        w2 = self.w2

        r0_centers = rs_waist
        q0_centers = (0, 0)
        k = 2 * np.pi / lamb
        r0_support = waist0 * self.waist0_factor  # *#(np.pi*num_points)**0.5*waist0
        x0, y0 = asbp.calc_xy(r0_support, num_points, r0_centers)

        # Create input beam and prepare for propagation to first surface.
        Er0 = asbp.calc_gaussian(k, x0, y0, waist0, r0s=rs_waist)

        profile0 = asbp.PlaneProfile(
            lamb, 1, source_z, r0_support, Er0,
            asbp.calc_gradxyE(r0_support, Er0, q0_centers), r0_centers,
            q0_centers)
        b0 = asbt1.Beam(profile0)
        s1 = rt1.Surface(rt1.SphericalProfile(roc1),
                         otk.h4t.make_translation(0, 0, w1),
                         interface=rt1.PerfectRefractor(ri.air, n))
        s2 = rt1.Surface(rt1.SphericalProfile(-roc2),
                         otk.h4t.make_translation(0, 0, w1 + d),
                         interface=rt1.PerfectRefractor(n, ri.air))
        s3 = rt1.Surface(rt1.PlanarProfile(),
                         otk.h4t.make_translation(0, 0, w1 + d + w2))

        segments = asbt1.trace_surfaces(
            b0, (s1, s2, s3), ('transmitted', 'transmitted', None))[0]
        b1_incident = segments[0].beams[1]
        b1_refracted = segments[1].beams[0]
        b1_plane = segments[1].planarized_beam
        b2_incident = segments[1].beams[1]
        b2_refracted = segments[2].beams[0]
        b2_plane = segments[2].planarized_beam
        b3 = segments[2].beams[1]
        # b1_incident = b0.propagate(s1, self.kz_mode)
        # b1_refracted = b1_incident.refract(s1, self.kz_mode)
        # b1_plane = b1_refracted.planarize(kz_mode=self.kz_mode, invert_kwargs=self.invert_kwargs)
        # b2_incident = b1_plane.propagate(s2, self.kz_mode)
        # b2_refracted = b2_incident.refract(s2, self.kz_mode)
        # b2_plane = b2_refracted.planarize(kz_mode=self.kz_mode, invert_kwargs=self.invert_kwargs)
        # b3 = b2_plane.propagate(s3, kz_mode=self.kz_mode)

        self.b0 = b0
        self.b1_incident = b1_incident
        self.b1_refracted = b1_refracted
        self.b1_plane = b1_plane
        self.b2_incident = b2_incident
        self.b2_plane = b2_plane
        self.b3 = b3
        waist3 = f * lamb / (np.pi * waist0)
        self.b3_scale = waist3 / waist0

        self.update_plots()
예제 #14
0
 def make(cls, x):
     if isinstance(x, ri.Index):
         return UniformIsotropic(x)
     else:
         n = float(x)
         return UniformIsotropic(ri.FixedIndex(n))
예제 #15
0
def test_pad_to_half_transform():
    l = trains.Train.make_singlet_transform2(ri.FixedIndex(1.5), 0.5, 0.1,
                                             0.01, 0.01)
    fp = 1
    lp = l.pad_to_half_transform(f=fp)
    assert np.allclose((lp + lp.reverse()).get_focal_lengths(), fp)