Beispiel #1
0
def test_intersect():
    import random
    random.seed(577)
    for i in range(100):
        R = random.gauss(25.0, 0.2)
        conic = random.uniform(-2.0, 1.0)
        ncoefs = random.randint(0, 4)
        coefs = [random.gauss(0, 1e-10) for i in range(ncoefs)]
        asphere = batoid.Asphere(R, conic, coefs)
        for j in range(100):
            x = random.gauss(0.0, 1.0)
            y = random.gauss(0.0, 1.0)

            # If we shoot rays straight up, then it's easy to predict the
            # intersection points.
            r0 = batoid.Ray(x, y, -10, 0, 0, 1, 0)
            r = asphere.intersect(r0)
            np.testing.assert_allclose(r.r[0], x)
            np.testing.assert_allclose(r.r[1], y)
            np.testing.assert_allclose(r.r[2],
                                       asphere.sag(x, y),
                                       rtol=0,
                                       atol=1e-9)

    # Check normal for R=0 paraboloid (a plane)
    asphere = batoid.Asphere(0.0, 0.0, [])
    np.testing.assert_array_equal(asphere.normal(0.1, 0.1), [0, 0, 1])
    # Check that normal parallelizes
    xs = np.random.normal(size=20)
    ys = np.random.normal(size=20)
    np.testing.assert_array_equal(
        asphere.normal(xs, ys),
        np.array([asphere.normal(x, y) for x, y in zip(xs, ys)]))
    # Test shape vectorization
    np.testing.assert_array_equal(
        asphere.normal(xs.reshape((10, 2)), ys.reshape((10, 2))),
        np.array([asphere.normal(x, y)
                  for x, y in zip(xs, ys)]).reshape(10, 2, 3))
    np.testing.assert_array_equal(
        asphere.normal(xs.reshape((2, 5, 2)), ys.reshape((2, 5, 2))),
        np.array([asphere.normal(x, y)
                  for x, y in zip(xs, ys)]).reshape(2, 5, 2, 3))
    # Also test non-unit strides on last index
    np.testing.assert_array_equal(
        asphere.normal(xs.reshape((10, 2))[::2],
                       ys.reshape((10, 2))[::2]),
        np.array([asphere.normal(x, y)
                  for x, y in zip(xs, ys)]).reshape(10, 2, 3)[::2])
Beispiel #2
0
def test_asphere_approximation():
    rng = np.random.default_rng(5772156)

    xs = np.linspace(-1, 1, 1000)
    ys = np.linspace(-1, 1, 1000)
    xtest = np.random.uniform(-0.9, 0.9, size=1000)
    ytest = np.random.uniform(-0.9, 0.9, size=1000)

    for i in range(10):
        R = rng.normal(20.0, 1.0)
        conic = rng.uniform(-2.0, 1.0)
        ncoef = rng.choice(4)
        coefs = [rng.normal(0, 1e-10) for i in range(ncoef)]
        asphere = batoid.Asphere(R, conic, coefs)
        zs = asphere.sag(*np.meshgrid(xs, ys))
        bc = batoid.Bicubic(xs, ys, zs)

        np.testing.assert_allclose(
            asphere.sag(xtest, ytest),
            bc.sag(xtest, ytest),
            atol=1e-12, rtol=0.0
        )

        np.testing.assert_allclose(
            asphere.normal(xtest, ytest),
            bc.normal(xtest, ytest),
            atol=1e-9, rtol=0
        )
def test_asphere_reflection_coordtransform():
    import random
    random.seed(5772156)
    asphere = batoid.Asphere(23.0, -0.97, [1e-5, 1e-6])
    for i in range(1000):
        x = random.gauss(0, 1)
        y = random.gauss(0, 1)
        vx = random.gauss(0, 1e-1)
        vy = random.gauss(0, 1e-1)
        v = np.array([vx, vy, 1])
        v /= np.linalg.norm(v)
        ray = batoid.Ray([x, y, -0.1], v, 0)
        ray2 = ray.copy()

        cs = batoid.CoordSys(
            [random.uniform(-0.01, 0.01),
             random.uniform(-0.01, 0.01),
             random.uniform(-0.01, 0.01)],
            (batoid.RotX(random.uniform(-0.01, 0.01))
             .dot(batoid.RotY(random.uniform(-0.01, 0.01)))
             .dot(batoid.RotZ(random.uniform(-0.01, 0.01)))
            )
        )

        rray = asphere.reflect(ray, coordSys=cs)
        rray2 = asphere.reflect(ray2.toCoordSys(cs))
        assert ray_isclose(rray, rray2)
def test_asphere_reflection_reversal():
    import random
    random.seed(5772156)
    asphere = batoid.Asphere(23.0, -0.97, [1e-5, 1e-6])
    for i in range(1000):
        x = random.gauss(0, 1)
        y = random.gauss(0, 1)
        vx = random.gauss(0, 1e-1)
        vy = random.gauss(0, 1e-1)
        v = np.array([vx, vy, 1])
        v /= np.linalg.norm(v)
        ray = batoid.Ray([x, y, -0.1], v, 0)
        rray = asphere.reflect(ray.copy())

        # Invert the reflected ray, and see that it ends back at the starting
        # point

        # Keep going a bit before turning around though
        turn_around = rray.positionAtTime(rray.t+0.1)
        return_ray = batoid.Ray(turn_around, -rray.v, -(rray.t+0.1))
        riray = asphere.intersect(return_ray.copy())
        # First check that we intersected at the same point
        np.testing.assert_allclose(rray.r[0], riray.r[0], rtol=0, atol=1e-9)
        np.testing.assert_allclose(rray.r[1], riray.r[1], rtol=0, atol=1e-9)
        np.testing.assert_allclose(rray.r[2], riray.r[2], rtol=0, atol=1e-9)
        # Reflect and propagate back to t=0.
        cray = asphere.reflect(return_ray.copy())
        cray = cray.positionAtTime(0)
        np.testing.assert_allclose(cray[0], x, rtol=0, atol=1e-9)
        np.testing.assert_allclose(cray[1], y, rtol=0, atol=1e-9)
        np.testing.assert_allclose(cray[2], -0.1, rtol=0, atol=1e-9)
Beispiel #5
0
def test_approximate_asphere():
    np.random.seed(57721)

    xs = np.linspace(-1, 1, 1000)
    ys = np.linspace(-1, 1, 1000)
    xtest = np.random.uniform(-0.9, 0.9, size=1000)
    ytest = np.random.uniform(-0.9, 0.9, size=1000)

    for i in range(50):
        R = np.random.normal(20.0, 1.0)
        conic = np.random.uniform(-2.0, 1.0)
        ncoef = np.random.randint(0, 4)
        coefs = [np.random.normal(0, 1e-10) for i in range(ncoef)]
        asphere = batoid.Asphere(R, conic, coefs)
        zs = asphere.sag(*np.meshgrid(xs, ys))
        bc = batoid.Bicubic(xs, ys, zs)

        np.testing.assert_allclose(asphere.sag(xtest, ytest),
                                   bc.sag(xtest, ytest),
                                   atol=1e-9,
                                   rtol=0.0)

        np.testing.assert_allclose(asphere.normal(xtest, ytest),
                                   bc.normal(xtest, ytest),
                                   atol=1e-8,
                                   rtol=0)
Beispiel #6
0
def test_rSplit():
    rng = np.random.default_rng(5)
    for _ in range(100):
        R = rng.normal(0.7, 0.8)
        conic = rng.uniform(-2.0, 1.0)
        ncoef = rng.integers(0, 5)
        coefs = [rng.normal(0, 1e-10) for i in range(ncoef)]
        asphere = batoid.Asphere(R, conic, coefs)

        theta_x = rng.normal(0.0, 1e-8)
        theta_y = rng.normal(0.0, 1e-8)
        rays = batoid.RayVector.asPolar(
            backDist=10.0, medium=batoid.Air(),
            wavelength=500e-9, outer=0.25*R,
            theta_x=theta_x, theta_y=theta_y,
            nrad=10, naz=10
        )
        coating = batoid.SimpleCoating(0.9, 0.1)
        reflectedRays = asphere.reflect(rays.copy(), coating=coating)
        m1 = batoid.Air()
        m2 = batoid.ConstMedium(1.1)
        refractedRays = asphere.refract(rays.copy(), m1, m2, coating=coating)
        refractedRays2, reflectedRays2 = asphere.rSplit(rays, m1, m2, coating)

        rays_allclose(reflectedRays, reflectedRays2)
        rays_allclose(refractedRays, refractedRays2)
Beispiel #7
0
def test_sag():
    rng = np.random.default_rng(57)
    for i in range(100):
        zmax = np.inf
        while zmax > 3.0:
            R = 0.0
            while abs(R) < 15.0:  # Don't allow too small radius of curvature
                R = 1. / rng.normal(0.0, 0.3)  # negative allowed
            conic = rng.uniform(-2.0, 1.0)
            ncoef = rng.choice(5)
            coefs = [rng.normal(0, 1e-8) for i in range(ncoef)]
            asphere = batoid.Asphere(R, conic, coefs)
            lim = min(0.7 * abs(R) / np.sqrt(1 + conic) if conic > -1 else 5,
                      5)
            zmax = abs(asphere.sag(lim, lim))
        for j in range(100):
            lim = 0.7 * abs(R) / np.sqrt(1 + conic) if conic > -1 else 1
            x = rng.uniform(-lim, lim)
            y = rng.uniform(-lim, lim)
            result = asphere.sag(x, y)
            np.testing.assert_allclose(result,
                                       asphere_sag(R, conic, coefs)(x, y))
            # Check that it returned a scalar float and not an array
            assert isinstance(result, float)
        # Check vectorization
        x = rng.uniform(-lim, lim, size=(10, 10))
        y = rng.uniform(-lim, lim, size=(10, 10))
        np.testing.assert_allclose(asphere.sag(x, y),
                                   asphere_sag(R, conic, coefs)(x, y))
        # Make sure non-unit stride arrays also work
        np.testing.assert_allclose(
            asphere.sag(x[::5, ::2], y[::5, ::2]),
            asphere_sag(R, conic, coefs)(x, y)[::5, ::2])
def test_asphere_refraction_plane():
    import random
    random.seed(57721)
    wavelength = 500e-9  # arbitrary
    asphere = batoid.Asphere(25.0, -0.97, [1e-3, 1e-5])
    m1 = batoid.ConstMedium(1.7)
    m2 = batoid.ConstMedium(1.2)
    for i in range(1000):
        x = random.gauss(0, 1)
        y = random.gauss(0, 1)
        vx = random.gauss(0, 1e-1)
        vy = random.gauss(0, 1e-1)
        v = normalized(np.array([vx, vy, 1]))/m1.getN(wavelength)
        ray = batoid.Ray((x, y, -0.1), (v[0], v[1], v[2]), 0)
        rray = asphere.refract(ray.copy(), m1, m2)
        np.testing.assert_allclose(np.linalg.norm(rray.v), 1./m2.getN(wavelength), rtol=1e-14)

        # ray.v, surfaceNormal, and rray.v should all be in the same plane, and
        # hence (ray.v x surfaceNormal) . rray.v should have zero magnitude.
        # magnitude zero.
        normal = asphere.normal(rray.r[0], rray.r[1])
        np.testing.assert_allclose(
            np.dot(np.cross(ray.v, normal), rray.v),
            0.0, rtol=0, atol=1e-14)

        # Test Snell's law
        np.testing.assert_allclose(
            m1.getN(wavelength)*np.linalg.norm(np.cross(normalized(ray.v), normal)),
            m2.getN(wavelength)*np.linalg.norm(np.cross(normalized(rray.v), normal)),
            rtol=0, atol=1e-15)
def test_table_medium_refraction():
    import random
    random.seed(57721566)

    filename = os.path.join(batoid.datadir, "media", "silica_dispersion.txt")
    wave, n = np.genfromtxt(filename).T
    table = batoid.Table(wave, n, batoid.Table.Interpolant.linear)
    silica = batoid.TableMedium(table)
    air = batoid.ConstMedium(1.000277)

    asphere = batoid.Asphere(25.0, -0.97, [1e-3, 1e-5])
    for i in range(10000):
        x = random.gauss(0, 1)
        y = random.gauss(0, 1)
        vx = random.gauss(0, 1e-1)
        vy = random.gauss(0, 1e-1)
        wavelength = random.uniform(0.3, 1.2)
        ray = batoid.Ray(x, y, -0.1, vx, vy, 1, 0, wavelength)

        cm1 = batoid.ConstMedium(silica.getN(wavelength))
        cm2 = batoid.ConstMedium(air.getN(wavelength))

        rray1 = asphere.refract(ray, silica, air)
        rray2 = asphere.refract(ray, cm1, cm2)

        assert rray1 == rray2
Beispiel #10
0
def test_intersect_vectorized():
    import random
    random.seed(5772)
    r0s = [
        batoid.Ray([
            random.gauss(0.0, 0.1),
            random.gauss(0.0, 0.1),
            random.gauss(10.0, 0.1)
        ], [
            random.gauss(0.0, 0.1),
            random.gauss(0.0, 0.1),
            random.gauss(-1.0, 0.1)
        ], random.gauss(0.0, 0.1)) for i in range(1000)
    ]
    r0s = batoid.RayVector(r0s)

    for i in range(100):
        R = random.gauss(25.0, 0.2)
        conic = random.uniform(-2.0, 1.0)
        ncoefs = random.randint(0, 4)
        coefs = [random.gauss(0, 1e-10) for i in range(ncoefs)]
        asphere = batoid.Asphere(R, conic, coefs)

        r1s = asphere.intersect(r0s)
        r2s = batoid.RayVector([asphere.intersect(r0) for r0 in r0s])
        np.testing.assert_allclose(asphere.sag(r1s.x, r1s.y),
                                   r1s.z,
                                   rtol=0,
                                   atol=1e-12)
        assert r1s == r2s
Beispiel #11
0
def test_fail():
    asphere = batoid.Asphere(1.0, 1.0, [1.0, 1.0])
    ray = batoid.Ray([0,0,-1], [0,0,-1])
    ray = asphere.intersect(ray)
    assert ray.failed

    ray = batoid.Ray([0,0,-1], [0,0,-1])
    asphere.intersect(ray)
    assert ray.failed
Beispiel #12
0
def test_fail():
    asphere = batoid.Asphere(1.0, 0.0, [])
    rv = batoid.RayVector(0, 10, 0, 0, 0, -1)  # Too far to the side
    rv2 = batoid.intersect(asphere, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([True]))
    # This one passes
    rv = batoid.RayVector(0, 0, -1, 0, 0, 1)
    rv2 = batoid.intersect(asphere, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([False]))
Beispiel #13
0
def test_properties():
    import random
    random.seed(5)
    for i in range(100):
        R = random.gauss(0.7, 0.8)
        conic = random.uniform(-2.0, 1.0)
        ncoef = random.randint(0, 4)
        coefs = [random.gauss(0, 1e-10) for i in range(ncoef)]
        asphere = batoid.Asphere(R, conic, coefs)
        assert asphere.R == R
        assert asphere.conic == conic
        assert asphere.coefs == coefs
        do_pickle(asphere)
Beispiel #14
0
def test_quad_plus_poly():
    import random
    random.seed(5772)
    for i in range(100):
        R = random.gauss(25.0, 0.2)
        conic = random.uniform(-2.0, 1.0)
        ncoefs = random.randint(0, 4)
        coefs = [random.gauss(0, 1e-10) for i in range(ncoefs)]
        asphere = batoid.Asphere(R, conic, coefs)
        quad = batoid.Quadric(R, conic)
        poly = py_poly(coefs)
        for j in range(100):
            x = random.gauss(0.0, 1.0)
            y = random.gauss(0.0, 1.0)
            np.testing.assert_allclose(asphere.sag(x, y), quad.sag(x, y)+poly(x, y))
Beispiel #15
0
def test_ne():
    objs = [
        batoid.Asphere(10.0, 1.0, []),
        batoid.Asphere(10.0, 1.0, [0]),
        batoid.Asphere(10.0, 1.0, [0,1]),
        batoid.Asphere(10.0, 1.0, [1,0]),
        batoid.Asphere(10.0, 1.1, []),
        batoid.Asphere(10.1, 1.0, []),
        batoid.Quadric(10.0, 1.0)
    ]
    all_obj_diff(objs)
def test_asphere_reflection_plane():
    import random
    random.seed(577215)
    asphere = batoid.Asphere(25.0, -0.97, [1e-3, 1e-5])
    for i in range(1000):
        x = random.gauss(0, 1)
        y = random.gauss(0, 1)
        vx = random.gauss(0, 1e-1)
        vy = random.gauss(0, 1e-1)
        ray = batoid.Ray((x, y, -0.1), (vx, vy, 1), 0)
        rray = asphere.reflect(ray.copy())

        # ray.v, surfaceNormal, and rray.v should all be in the same plane, and
        # hence (ray.v x surfaceNormal) . rray.v should have zero magnitude.
        # magnitude zero.
        np.testing.assert_allclose(
            np.dot(np.cross(ray.v, asphere.normal(rray.r[0], rray.r[1])), rray.v),
            0.0, rtol=0, atol=1e-15)
Beispiel #17
0
def test_rSplit():
    for i in range(100):
        R = np.random.normal(0.7, 0.8)
        conic = np.random.uniform(-2.0, 1.0)
        ncoef = np.random.randint(0, 4)
        coefs = [np.random.normal(0, 1e-10) for i in range(ncoef)]
        asphere = batoid.Asphere(R, conic, coefs)

        rays = batoid.rayGrid(10, 2*R, 0.0, 0.0, -1.0, 16, 500e-9, 1.0, batoid.Air())
        coating = batoid.SimpleCoating(0.9, 0.1)
        reflectedRays = asphere.reflect(rays, coating)
        m1 = batoid.Air()
        m2 = batoid.ConstMedium(1.1)
        refractedRays = asphere.refract(rays, m1, m2, coating)
        reflectedRays2, refractedRays2 = asphere.rSplit(rays, m1, m2, coating)

        assert reflectedRays == reflectedRays2
        assert refractedRays == refractedRays2
Beispiel #18
0
def test_refract():
    rng = np.random.default_rng(577215)
    size = 10_000
    for i in range(100):
        zmax = np.inf
        while zmax > 3.0:
            R = 0.0
            while abs(R) < 15.0:  # Don't allow too small radius of curvature
                R = 1. / rng.normal(0.0, 0.3)  # negative allowed
            conic = rng.uniform(-2.0, 1.0)
            ncoef = rng.choice(5)
            coefs = [rng.normal(0, 1e-8) for i in range(ncoef)]
            asphere = batoid.Asphere(R, conic, coefs)
            lim = min(0.7 * abs(R) / np.sqrt(1 + conic) if conic > -1 else 5,
                      5)
            zmax = abs(asphere.sag(lim, lim))
        m0 = batoid.ConstMedium(rng.normal(1.2, 0.01))
        m1 = batoid.ConstMedium(rng.normal(1.3, 0.01))
        x = rng.uniform(-lim, lim, size=size)
        y = rng.uniform(-lim, lim, size=size)
        z = np.full_like(x, -10.0)
        vx = rng.uniform(-1e-5, 1e-5, size=size)
        vy = rng.uniform(-1e-5, 1e-5, size=size)
        vz = np.sqrt(1 - vx * vx - vy * vy) / m0.n
        rv = batoid.RayVector(x, y, z, vx, vy, vz, t=0)
        rvr = batoid.refract(asphere, rv.copy(), m0, m1)
        rvr2 = asphere.refract(rv.copy(), m0, m1)
        rays_allclose(rvr, rvr2)
        # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
        normal = asphere.normal(rvr.x, rvr.y)

        # Test Snell's law
        s0 = np.sum(np.cross(normal, rv.v * m0.n)[~rvr.failed], axis=-1)
        s1 = np.sum(np.cross(normal, rvr.v * m1.n)[~rvr.failed], axis=-1)
        np.testing.assert_allclose(m0.n * s0, m1.n * s1, rtol=0, atol=1e-9)

        # Test that rv.v, rvr.v and normal are all in the same plane
        np.testing.assert_allclose(np.einsum("ad,ad->a",
                                             np.cross(normal, rv.v),
                                             rv.v)[~rvr.failed],
                                   0.0,
                                   rtol=0,
                                   atol=1e-12)
Beispiel #19
0
def test_properties():
    rng = np.random.default_rng(5)
    for i in range(100):
        zmax = np.inf
        while zmax > 3.0:
            R = 0.0
            while abs(R) < 15.0:  # Don't allow too small radius of curvature
                R = 1. / rng.normal(0.0, 0.3)  # negative allowed
            conic = rng.uniform(-2.0, 1.0)
            ncoef = rng.choice(5)
            coefs = [rng.normal(0, 1e-8) for i in range(ncoef)]
            asphere = batoid.Asphere(R, conic, coefs)
            lim = min(0.7 * abs(R) / np.sqrt(1 + conic) if conic > -1 else 5,
                      5)
            zmax = abs(asphere.sag(lim, lim))
        assert asphere.R == R
        assert asphere.conic == conic
        assert np.array_equal(asphere.coefs, coefs)
        do_pickle(asphere)
Beispiel #20
0
def test_reflect():
    rng = np.random.default_rng(57721)
    size = 10_000
    for i in range(100):
        zmax = np.inf
        while zmax > 3.0:
            R = 0.0
            while abs(R) < 15.0:  # Don't allow too small radius of curvature
                R = 1. / rng.normal(0.0, 0.3)  # negative allowed
            conic = rng.uniform(-2.0, 1.0)
            ncoef = rng.choice(5)
            coefs = [rng.normal(0, 1e-8) for i in range(ncoef)]
            asphere = batoid.Asphere(R, conic, coefs)
            lim = min(0.7 * abs(R) / np.sqrt(1 + conic) if conic > -1 else 5,
                      5)
            zmax = abs(asphere.sag(lim, lim))
        x = rng.uniform(-lim, lim, size=size)
        y = rng.uniform(-lim, lim, size=size)
        z = np.full_like(x, -10.0)
        vx = rng.uniform(-1e-5, 1e-5, size=size)
        vy = rng.uniform(-1e-5, 1e-5, size=size)
        vz = np.full_like(x, 1)
        rv = batoid.RayVector(x, y, z, vx, vy, vz)
        rvr = batoid.reflect(asphere, rv.copy())
        rvr2 = asphere.reflect(rv.copy())
        rays_allclose(rvr, rvr2)
        # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
        normal = asphere.normal(rvr.x, rvr.y)

        # Test law of reflection
        a0 = np.einsum("ad,ad->a", normal, rv.v)[~rvr.failed]
        a1 = np.einsum("ad,ad->a", normal, -rvr.v)[~rvr.failed]
        np.testing.assert_allclose(a0, a1, rtol=0, atol=1e-12)

        # Test that rv.v, rvr.v and normal are all in the same plane
        np.testing.assert_allclose(np.einsum("ad,ad->a",
                                             np.cross(normal, rv.v),
                                             rv.v)[~rvr.failed],
                                   0.0,
                                   rtol=0,
                                   atol=1e-12)
def test_asphere_refraction_reversal():
    import random
    random.seed(577215)
    wavelength = 500e-9  # arbitrary
    asphere = batoid.Asphere(23.0, -0.97, [1e-5, 1e-6])
    m1 = batoid.ConstMedium(1.7)
    m2 = batoid.ConstMedium(1.9)
    for i in range(1000):
        x = random.gauss(0, 1)
        y = random.gauss(0, 1)
        vx = random.gauss(0, 1e-1)
        vy = random.gauss(0, 1e-1)
        ray = batoid.Ray([x, y, -0.1],
                         normalized(np.array([vx, vy, 1])) /
                         m1.getN(wavelength), 0)
        rray = asphere.refract(ray, m1, m2)
        np.testing.assert_allclose(np.linalg.norm(rray.v),
                                   1. / m2.getN(wavelength),
                                   rtol=1e-15)

        # Invert the refracted ray, and see that it ends back at the starting
        # point

        # Keep going a bit before turning around though
        turn_around = rray.positionAtTime(rray.t + 0.1)
        return_ray = batoid.Ray(turn_around, -rray.v, -(rray.t + 0.1))
        riray = asphere.intersect(return_ray)
        # First check that we intersected at the same point
        np.testing.assert_allclose(rray.r[0], riray.r[0], rtol=0, atol=1e-10)
        np.testing.assert_allclose(rray.r[1], riray.r[1], rtol=0, atol=1e-10)
        np.testing.assert_allclose(rray.r[2], riray.r[2], rtol=0, atol=1e-10)
        # Refract and propagate back to t=0.
        cray = asphere.refract(return_ray, m2, m1)
        np.testing.assert_allclose(np.linalg.norm(cray.v),
                                   1. / m1.getN(wavelength),
                                   rtol=1e-15)
        cpoint = cray.positionAtTime(0)
        np.testing.assert_allclose(cpoint[0], x, rtol=0, atol=1e-10)
        np.testing.assert_allclose(cpoint[1], y, rtol=0, atol=1e-10)
        np.testing.assert_allclose(cpoint[2], -0.1, rtol=0, atol=1e-10)
Beispiel #22
0
def test_sag():
    import random
    random.seed(57)
    for i in range(100):
        R = random.gauss(25.0, 0.2)
        conic = random.uniform(-2.0, 1.0)
        ncoefs = random.randint(0, 4)
        coefs = [random.gauss(0, 1e-10) for i in range(ncoefs)]
        asphere = batoid.Asphere(R, conic, coefs)
        for j in range(100):
            x = random.gauss(0.0, 1.0)
            y = random.gauss(0.0, 1.0)
            result = asphere.sag(x, y)
            np.testing.assert_allclose(result,
                                       py_asphere(R, conic, coefs)(x, y))
            # Check that it returned a scalar float and not an array
            assert isinstance(result, float)
        # Check vectorization
        x = np.random.normal(0.0, 1.0, size=(10, 10))
        y = np.random.normal(0.0, 1.0, size=(10, 10))
        # Make sure non-unit stride arrays also work
        np.testing.assert_allclose(asphere.sag(x[::5, ::2], y[::5, ::2]),
                                   py_asphere(R, conic, coefs)(x, y)[::5, ::2])
Beispiel #23
0
def test_intersect():
    rng = np.random.default_rng(5772)
    size = 10_000
    for i in range(100):
        zmax = np.inf
        while zmax > 3.0:
            R = 0.0
            while abs(R) < 15.0:  # Don't allow too small radius of curvature
                R = 1. / rng.normal(0.0, 0.3)  # negative allowed
            conic = rng.uniform(-2.0, 1.0)
            ncoef = rng.choice(5)
            coefs = [rng.normal(0, 1e-8) for i in range(ncoef)]
            asphere = batoid.Asphere(R, conic, coefs)
            lim = min(0.7 * abs(R) / np.sqrt(1 + conic) if conic > -1 else 5,
                      5)
            zmax = abs(asphere.sag(lim, lim))
        asphereCoordSys = batoid.CoordSys(origin=[0, 0, -1])
        x = rng.uniform(-lim, lim, size=size)
        y = rng.uniform(-lim, lim, size=size)
        z = np.full_like(x, -10.0)
        # If we shoot rays straight up, then it's easy to predict the
        # intersection
        vx = np.zeros_like(x)
        vy = np.zeros_like(x)
        vz = np.ones_like(x)
        rv = batoid.RayVector(x, y, z, vx, vy, vz)
        np.testing.assert_allclose(rv.z, -10.0)
        rv2 = batoid.intersect(asphere, rv.copy(), asphereCoordSys)
        assert rv2.coordSys == asphereCoordSys

        rv2 = rv2.toCoordSys(batoid.CoordSys())
        np.testing.assert_allclose(rv2.x, x)
        np.testing.assert_allclose(rv2.y, y)
        np.testing.assert_allclose(rv2.z,
                                   asphere.sag(x, y) - 1,
                                   rtol=0,
                                   atol=1e-12)

        # Straight down works too.
        rv2 = rv.copy()
        rv2.vz[:] *= -1
        rv2 = batoid.intersect(asphere, rv.copy(), asphereCoordSys)
        assert rv2.coordSys == asphereCoordSys

        rv2 = rv2.toCoordSys(batoid.CoordSys())
        np.testing.assert_allclose(rv2.x, x)
        np.testing.assert_allclose(rv2.y, y)
        np.testing.assert_allclose(rv2.z,
                                   asphere.sag(x, y) - 1,
                                   rtol=0,
                                   atol=1e-12)

        # Check default intersect coordTransform
        rv2 = rv.copy().toCoordSys(asphereCoordSys)
        batoid.intersect(asphere, rv2)
        assert rv2.coordSys == asphereCoordSys
        rv2 = rv2.toCoordSys(batoid.CoordSys())
        np.testing.assert_allclose(rv2.x, x)
        np.testing.assert_allclose(rv2.y, y)
        np.testing.assert_allclose(rv2.z,
                                   asphere.sag(x, y) - 1,
                                   rtol=0,
                                   atol=1e-12)