Example #1
0
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)
Example #2
0
def test_pbg_calc_field():
    origin = v4hb.stack_xyzw(0, 0, 0, 1)
    vector = v4hb.stack_xyzw(0, 0, 1, 0)
    axis1 = v4hb.normalize(v4hb.stack_xyzw(1, 1j, 0.5j, 0))
    lamb = 860e-9
    k = 2*np.pi/lamb
    waist = 100e-6
    z_R = np.pi*waist**2/lamb
    z_waist = 1*z_R
    mode = pbg.Mode.make(rt1.Line(origin, vector), axis1, lamb, waist, z_waist)[0]

    z = np.linspace(-z_R*16, z_R*16, 200)[:, None]
    x = np.arange(3)[:, None, None]*waist
    #zv, xv = [array.ravel() for array in np.broadcast_arrays(zs, xs)]
    points = v4hb.concatenate_xyzw(x, 0, z, 1)
    field, phi_axis, grad_phi = mode.calc_field(k, points, calc_grad_phi=True)
    psis = field*mathx.expj(-z*k)
    psis_true = beams.FundamentalGaussian(lamb, w_0=waist, flux=1).E(z - z_waist, x)*np.exp(
        -1j*np.arctan(z_waist/z_R))

    assert np.allclose(psis, psis_true)



    if 0: # Useful for testing in IPython.
        glw = pg.GraphicsLayoutWidget()
        absz_plot = glw.addAlignedPlot()
        glw.nextRows()
        phase_plot = glw.addAlignedPlot()
        for x, color, psi, psi_true in zip(xs, pg.tableau10, psis.T, psis_true.T):
            absz_plot.plot(zs[:, 0]*1e3, abs(psi), pen=color)
            absz_plot.plot(zs[:, 0]*1e3, abs(psi_true), pen=pg.mkPen(color, style=pg.DashLine))
            phase_plot.plot(zs[:, 0]*1e3, np.angle(psi), pen=color)
            phase_plot.plot(zs[:, 0]*1e3, np.angle(psi_true), pen=pg.mkPen(color, style=pg.DashLine))
        glw.show()
Example #3
0
def test_pbg_project_field():
    # Define a fundamental Gaussian beam point along z axis.
    lamb = 860e-9
    k = 2*np.pi/lamb
    waist = 10e-6
    flux = 2
    beam = beams.FundamentalGaussian(lamb=lamb, w_0=waist, flux=flux)
    z_waist = beam.z_R # Put waist of Gaussian at one Rayleigh range.
    z = 2*beam.z_R # Sample at two Rayleigh ranges.
    y = np.linspace(-0.5, 0.5, 16)[:, None]*6*waist
    x = np.linspace(-0.5, 0.5, 16)[:, None, None]*6*waist
    Er = beam.E(z - z_waist, (x**2 + y**2)**0.5)*np.exp(1j*k*z)
    Er *= np.exp(1j*beam.Gouy(-z_waist)) # Want phase at origin to be zero for comparison below.

    # Define a set of PBGs of different angles with same waist plane as Er.
    origin = v4hb.stack_xyzw(0, 0, 0, 1)
    thetay = np.linspace(-0.5, 0.5, 3)[:, None]*6*lamb/(np.pi*waist)
    thetax = np.linspace(-0.5, 0.5, 3)[:, None, None]*6*lamb/(np.pi*waist)
    vector = v4hb.normalize(v4hb.concatenate_xyzw(thetax, thetay, 1, 0))
    axis1 = v4hb.normalize(v4hb.stack_xyzw(1, 0, 0, 0))
    mode_bundle = pbg.Mode.make(rt1.Line(origin, vector), axis1, lamb, waist, z_waist)[0]

    flux_, phi_axis_origin_, projected_field = mode_bundle.project_field(k, v4hb.concatenate_xyzw(x, y, z, 1), Er)
    coefficients = flux_**0.5 * np.exp(1j*phi_axis_origin_)
    testing.assert_allclose(coefficients, np.asarray([[0, 0, 0], [0, flux**0.5, 0], [0, 0, 0]])[:, :, None], atol=1e-10)

# TODO restore me
# def test_pbg_collimate(qtbot):
#     lamb = 860e-9
#     waist = 10e-6
#     n1 = 1.5
#     n2 = 3
#     f = 0.1
#     surface = rt.Surface(rt.SphericalProfile(f*(n2 - n1)), interface=rt.FresnelInterface(ri.FixedIndex(n1), ri.FixedIndex(n2)))
#     line_base = otk.rt.lines.Line([0, 0, -f*n1, 1], [0, 0, 1, 0])
#     beam0 = pbg.Beam.make(line_base, [1, 0, 0, 0], lamb, waist, [1,0,0,0], 1, n=n1)
#     surfaces = (surface, )
#     segments = pbg.trace_surfaces(surfaces, ['transmitted'], beam0)
#     assert len(segments) == 2
#     beam1 = segments[1].beam
#     assert beam1.n == n2
#     assert np.isclose(beam1.flux, abs(omath.calc_fresnel_coefficients(n1, n2, 1)[1][0])**2*n2/n1)
#     for surface_index in range(2): # TODO fix this
#         widget = segments[-1].make_profile_widget(0)
#         qtbot.addWidget(widget)
Example #4
0
def test_pbg_transform_advance():
    # Check that the field of a totally non-degenerate PBG is identical under all sorts of transforms.
    lamb = 860e-9
    k = 2*np.pi/lamb
    waist1 = 100e-6  # + 0e-6j
    waist2 = 50e-6
    z_R = np.pi*waist1**2/lamb
    x0 = 1
    y0 = 2
    z0 = 3
    origin = v4hb.stack_xyzw(x0, y0, z0, 1)
    vector = v4hb.normalize(v4hb.stack_xyzw(0, 0, 1, 0))
    axis1 = v4hb.normalize(v4hb.stack_xyzw(1 + 1j, 1, 0, 0))

    z_waist1 = (1 + 1j)*z_R
    z_waist2 = (2 - 1j)*z_R
    mode = pbg.Mode.make(otk.rt1._lines.Line(origin, vector), axis1, lamb, waist1, z_waist1, waist2, z_waist2)[0]
    z = np.linspace(-z_R*16, z_R*16, 200)[:, None] + z0
    rho = np.arange(3)[:, None, None]*waist1
    theta = np.pi/4
    x = np.cos(theta)*rho + x0
    y = np.sin(theta)*rho + y0
    points = v4hb.concatenate_xyzw(x, y, z, 1)
    field, phi_axis, grad_phi = mode.calc_field(k, points, calc_grad_phi=True)
    #print(abs(field).max()) # Check we don't have all zeros.

    matrices = [otk.h4t.make_translation(-1, 2, 3), otk.h4t.make_scaling(-1, -1, -1),
                np.array([[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]),
                np.array([[0, -1, 0, 0], [1, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])]

    advances = [0, 0.2]

    for advance in advances:
        modep, phi_axis_origin = mode.advance(k, advance)
        for matrix in matrices:
            modepp = modep.transform(matrix)
            pointsp = v4hb.transform(points, matrix)

            fieldp, phi_axisp, grad_phipp = modepp.calc_field(k, pointsp, 1, phi_axis_origin, calc_grad_phi=True)
            grad_phip = grad_phipp.dot(np.linalg.inv(matrix))

            assert np.allclose(fieldp, field)
            assert np.allclose(phi_axisp, phi_axis)
            assert np.allclose(grad_phip, grad_phi)
Example #5
0
def test_make_rotation():
    for vector in ([1, 0, 0], [0, 1, 0], [0, 0, 1], v4hb.normalize([1, -1,
                                                                    2])):
        testing.assert_allclose(otk.h4t.make_rotation(vector, 0), np.eye(4))

    for theta in (np.pi / 4, 5 * np.pi / 4):
        testing.assert_allclose(otk.h4t.make_rotation([0, 1, 0], theta),
                                otk.h4t.make_y_rotation(theta))
        testing.assert_allclose(otk.h4t.make_rotation([0, 0, 1], theta),
                                otk.h4t.make_z_rotation(theta))
Example #6
0
def test_pbg_simple():
    waist = 100e-6
    n = 1
    lamb = 800e-9
    k = 2*np.pi*n/lamb
    # Totally arbitrary origin and axes.
    origin = np.asarray([1, 2, 3, 1])
    vector = v4hb.normalize(np.asarray([1, -2, -1, 0]))
    axis_x = v4hb.normalize(np.asarray([1, 1, 0, 0]))

    mode, (axis_x, axis_y) = pbg.Mode.make(otk.rt1._lines.Line(origin, vector), axis_x, lamb / n, waist)

    z_R = waist**2*k/2
    z = np.asarray([-10, 1, 0, 1, 10])[:, None]*z_R*0
    x = np.arange(3)[:, None, None]*waist
    y = np.arange(3)[:, None, None, None]*waist
    #z = np.asarray([[z_R]])
    #x = np.asarray([[waist]])
    #y = np.asarray([[waist]])
    rho = (x**2 + y**2)**0.5
    xhat = np.asarray([1, 0, 0, 0])
    yhat = np.asarray([0, 1, 0, 0])
    rhohat = mathx.divide0(xhat*x + yhat*y, rho)
    mode_matrix = np.stack([axis_x, axis_y, vector, origin], 0)
    points = v4hb.concatenate_xyzw(x, y, z, 1).dot(mode_matrix)

    field, phi_axis, grad_phi = mode.calc_field(k, points, calc_grad_phi=True)

    beam = beams.FundamentalGaussian(lamb/n, w_0=waist, flux=1)
    field_true = beam.E(z, rho)*mathx.expj(z*k)
    field_true_axis = beam.E(z, 0)*mathx.expj(z*k)
    grad_phi_true = (beam.dphidz(z, rho) + k)*vector + beam.dphidrho(z, rho)*rhohat.dot(mode_matrix)

    testing.assert_allclose(abs(field), abs(field_true))
    testing.assert_allclose(field, field_true)

    testing.assert_allclose(abs(mathx.wrap_to_pm(phi_axis - np.angle(field_true_axis), np.pi)), 0, atol=1e-6)

    testing.assert_allclose(grad_phi, grad_phi_true, atol=1e-6)
Example #7
0
def test_ConicProfile():
    p = _profiles.ConicProfile(10, 0.5, [0.05])
    origin = v4hb.stack_xyzw([1, -1.1, 0, 0], [0, 0, -1.2, 1.3],
                             [-1, -1.1, -1.2, -1.3], 1)
    vector = v4hb.normalize(
        v4hb.stack_xyzw([0.1, 0.2, -0.1, 0.1], [-0.1, -0.1, 0.2, 0.2],
                        [1, 1, 1, 1], 0))
    pd = p.intersect(origin, vector)
    point = origin + pd * vector
    rho = v4hb.dot(point[..., :2])**0.5
    assert np.allclose(p.calc_z(rho), point[..., [2]])

    p.calc_normal(point)
Example #8
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))
Example #9
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))