Пример #1
0
def test_ne():
    objs = [
        batoid.Sphere(1.0),
        batoid.Sphere(2.0),
        batoid.Plane()
    ]
    all_obj_diff(objs)
Пример #2
0
def test_sag():
    np.random.seed(57)
    for _ in range(100):
        s1 = batoid.Sphere(np.random.uniform(1, 3))
        s2 = batoid.Paraboloid(np.random.uniform(1, 3))
        sum = batoid.Sum([s1, s2])

        x = np.random.normal(size=5000)
        y = np.random.normal(size=5000)

        np.testing.assert_allclose(
            sum.sag(x, y),
            s1.sag(x, y) + s2.sag(x, y),
            rtol=1e-12,
            atol=1e-12
        )

        s3 = batoid.Quadric(np.random.uniform(3, 5), np.random.uniform(-0.1, 0.1))
        sum2 = batoid.Sum([s1, s2, s3])

        np.testing.assert_allclose(
            sum2.sag(x, y),
            s1.sag(x, y) + s2.sag(x, y) + s3.sag(x, y),
            rtol=1e-12,
            atol=1e-12
        )
Пример #3
0
def test_refract():
    rng = np.random.default_rng(577215)
    size = 10_000
    for _ in range(100):
        s1 = batoid.Sphere(1. / rng.normal(0., 0.2))
        s2 = batoid.Paraboloid(rng.uniform(1, 3))
        sum = batoid.Sum([s1, s2])
        m0 = batoid.ConstMedium(rng.normal(1.2, 0.01))
        m1 = batoid.ConstMedium(rng.normal(1.3, 0.01))
        x = rng.uniform(-1, 1, size=size)
        y = rng.uniform(-1, 1, 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)
        rvr = batoid.refract(sum, rv.copy(), m0, m1)
        rvr2 = sum.refract(rv.copy(), m0, m1)
        rays_allclose(rvr, rvr2)
        # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
        normal = sum.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)
Пример #4
0
def test_reflect():
    rng = np.random.default_rng(57721)
    size = 10_000
    for _ in range(100):
        s1 = batoid.Sphere(1. / rng.normal(0., 0.2))
        s2 = batoid.Paraboloid(rng.uniform(1, 3))
        sum = batoid.Sum([s1, s2])
        x = rng.uniform(-1, 1, size=size)
        y = rng.uniform(-1, 1, 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(sum, rv.copy())
        rvr2 = sum.reflect(rv.copy())
        rays_allclose(rvr, rvr2)
        # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
        normal = sum.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)
Пример #5
0
def test_fail():
    surface = batoid.Sphere(1.0)
    ray = batoid.Ray([0, 10, -1], [0, 0, 1])

    ray = surface.intersect(ray)
    assert ray.failed
    do_pickle(ray)
Пример #6
0
def test_properties():
    np.random.seed(5)
    for _ in range(100):
        s1 = batoid.Sphere(np.random.uniform(1, 3))
        s2 = batoid.Paraboloid(np.random.uniform(1, 3))
        sum = batoid.Sum([s1, s2])
        do_pickle(sum)
        # check commutativity
        assert sum == batoid.Sum([s2, s1])

        # order of sum.surfaces is not guaranteed
        assert s1 in sum.surfaces
        assert s2 in sum.surfaces

        s3 = batoid.Quadric(np.random.uniform(3, 5), np.random.uniform(-0.1, 0.1))
        sum2 = batoid.Sum([s1, s2, s3])
        do_pickle(sum2)
        # check commutativity
        assert sum2 == batoid.Sum([s2, s3, s1])
        assert sum2 == batoid.Sum([s3, s1, s2])
        assert sum2 == batoid.Sum([s3, s2, s1])
        assert sum2 == batoid.Sum([s2, s1, s3])
        assert sum2 == batoid.Sum([s1, s3, s2])

        assert s1 in sum2.surfaces
        assert s2 in sum2.surfaces
        assert s3 in sum2.surfaces

        do_pickle(sum)
Пример #7
0
def test_add_plane():
    np.random.seed(577)
    for _ in range(100):
        # Adding a plane should have zero effect on sag or normal vector
        s1 = batoid.Sphere(np.random.uniform(1, 3))
        s2 = batoid.Plane()
        sum = batoid.Sum([s1, s2])

        x = np.random.normal(size=5000)
        y = np.random.normal(size=5000)

        np.testing.assert_allclose(
            sum.sag(x, y),
            s1.sag(x, y),
            rtol=1e-12,
            atol=1e-12
        )

        for _x, _y in zip(x[:100], y[:100]):
            np.testing.assert_allclose(
                sum.normal(_x, _y),
                s1.normal(_x, _y),
                rtol=1e-12,
                atol=1e-12
            )
Пример #8
0
def test_properties():
    rng = np.random.default_rng(5)
    for i in range(100):
        R = rng.normal(0.0, 0.3)  # negative allowed
        sphere = batoid.Sphere(R)
        assert sphere.R == R
        do_pickle(sphere)
Пример #9
0
def test_normal():
    rng = np.random.default_rng(577)
    for i in range(100):
        R = 1. / rng.normal(0.0, 0.3)
        sphere = batoid.Sphere(R)
        for j in range(10):
            x = rng.uniform(-0.7 * abs(R), 0.7 * abs(R))
            y = rng.uniform(-0.7 * abs(R), 0.7 * abs(R))
            result = sphere.normal(x, y)
            r = np.hypot(x, y)
            rat = r / R
            dzdr = rat / np.sqrt(1 - rat * rat)
            nz = 1 / np.sqrt(1 + dzdr * dzdr)
            normal = np.array([-x / r * dzdr * nz, -y / r * dzdr * nz, nz])
            np.testing.assert_allclose(result, normal)
        # Check 0,0
        np.testing.assert_equal(sphere.normal(0, 0), np.array([0, 0, 1]))
        # Check vectorization
        x = rng.uniform(-0.7 * abs(R), 0.7 * abs(R), size=(10, 10))
        y = rng.uniform(-0.7 * abs(R), 0.7 * abs(R), size=(10, 10))
        r = np.hypot(x, y)
        rat = r / R
        dzdr = rat / np.sqrt(1 - rat * rat)
        nz = 1 / np.sqrt(1 + dzdr * dzdr)
        normal = np.dstack([-x / r * dzdr * nz, -y / r * dzdr * nz, nz])
        np.testing.assert_allclose(sphere.normal(x, y), normal)
        # Make sure non-unit stride arrays also work
        np.testing.assert_allclose(sphere.normal(x[::5, ::2], y[::5, ::2]),
                                   normal[::5, ::2])
Пример #10
0
def test_sag():
    rng = np.random.default_rng(57)
    for i in range(100):
        R = 1. / rng.normal(0.0, 0.3)
        sphere = batoid.Sphere(R)
        for j in range(10):
            x = rng.uniform(-0.7 * abs(R), 0.7 * abs(R))
            y = rng.uniform(-0.7 * abs(R), 0.7 * abs(R))
            result = sphere.sag(x, y)
            np.testing.assert_allclose(
                result, R * (1 - np.sqrt(1.0 - (x * x + y * y) / R / R)))
            # Check that it returned a scalar float and not an array
            assert isinstance(result, float)
        # Check 0,0
        np.testing.assert_allclose(sphere.sag(0, 0), 0.0, rtol=0, atol=1e-17)
        # Check vectorization
        x = rng.uniform(-0.7 * abs(R), 0.7 * abs(R), size=(10, 10))
        y = rng.uniform(-0.7 * abs(R), 0.7 * abs(R), size=(10, 10))
        np.testing.assert_allclose(
            sphere.sag(x, y), R * (1 - np.sqrt(1.0 - (x * x + y * y) / R / R)))
        # Make sure non-unit stride arrays also work
        np.testing.assert_allclose(
            sphere.sag(x[::5, ::2], y[::5, ::2]),
            R * (1 - np.sqrt(1.0 - (x * x + y * y) / R / R))[::5, ::2])
        do_pickle(sphere)
Пример #11
0
def test_reflect():
    rng = np.random.default_rng(57721)
    size = 10_000
    for i in range(100):
        R = 1. / rng.normal(0.0, 0.3)
        sphere = batoid.Sphere(R)
        x = rng.uniform(-0.3 * abs(R), 0.3 * abs(R), size=size)
        y = rng.uniform(-0.3 * abs(R), 0.3 * abs(R), size=size)
        z = np.full_like(x, -2 * abs(R))
        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(sphere, rv.copy())
        rvr2 = sphere.reflect(rv.copy())
        rays_allclose(rvr, rvr2)
        # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
        normal = sphere.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)
Пример #12
0
def test_intersect():
    np.random.seed(57721)
    rv0 = batoid.RayVector([
        batoid.Ray(
            np.random.normal(scale=0.1),
            np.random.normal(scale=0.1),
            10,
            np.random.normal(scale=1e-4),
            np.random.normal(scale=1e-4),
            -1
        )
        for _ in range(100)
    ])
    for _ in range(100):
        s1 = batoid.Sphere(np.random.uniform(3, 10))
        s2 = batoid.Paraboloid(np.random.uniform(3, 10))
        sum = batoid.Sum([s1, s2])

        rv = batoid.RayVector(rv0)
        rv1 = sum.intersect(rv)
        rv2 = batoid.RayVector([sum.intersect(r) for r in rv])
        rv3 = batoid.RayVector(rv)
        sum.intersectInPlace(rv)

        for r in rv3:
            sum.intersectInPlace(r)

        assert rays_allclose(rv1, rv)
        assert rays_allclose(rv2, rv)
        assert rays_allclose(rv3, rv)
Пример #13
0
def test_ne():
    objs = [
        batoid.Quadric(10.0, 1.0),
        batoid.Quadric(11.0, 1.0),
        batoid.Quadric(10.0, 1.1),
        batoid.Sphere(10.0)
    ]
    all_obj_diff(objs)
Пример #14
0
def test_properties():
    import random
    random.seed(5)
    for i in range(100):
        R = random.gauss(0.7, 0.8)
        sphere = batoid.Sphere(R)
        assert sphere.R == R
        do_pickle(sphere)
Пример #15
0
def test_fail():
    sum = batoid.Sum([batoid.Plane(), batoid.Sphere(1.0)])
    rv = batoid.RayVector(0, 10, 0, 0, 0, -1)  # Too far to side
    rv2 = batoid.intersect(sum, 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(sum, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([False]))
Пример #16
0
def test_fail():
    sphere = batoid.Sphere(1.0)
    ray = batoid.Ray([0,0,-1], [0,0,-1])
    ray = sphere.intersect(ray)
    assert ray.failed

    ray = batoid.Ray([0,0,-1], [0,0,-1])
    sphere.intersect(ray)
    assert ray.failed
Пример #17
0
def test_fail():
    sum = batoid.Sum([batoid.Plane(), batoid.Sphere(1.0)])
    ray = batoid.Ray([0,0,sum.sag(0,0)-1], [0,0,-1])
    ray = sum.intersect(ray)
    assert ray.failed

    ray = batoid.Ray([0,0,sum.sag(0,0)-1], [0,0,-1])
    sum.intersectInPlace(ray)
    assert ray.failed
Пример #18
0
def wavefront(optic, theta_x, theta_y, wavelength, nx=32, sphereRadius=None):
    """Compute wavefront.

    Parameters
    ----------
    optic : batoid.Optic
        Optic for which to compute wavefront.
    theta_x, theta_y : float
        Field of incoming rays (gnomic projection)
    wavelength : float
        Wavelength of incoming rays
    nx : int, optional
        Size of ray grid to generate to compute wavefront.  Default: 32
    sphereRadius : float, optional
        Radius of reference sphere in meters.  If None, then use optic.sphereRadius.

    Returns
    -------
    wavefront : batoid.Lattice
        A batoid.Lattice object containing the wavefront values in waves and
        the primitive lattice vectors of the entrance pupil grid in meters.
    """
    dirCos = gnomicToDirCos(theta_x, theta_y)
    rays = batoid.rayGrid(
        optic.dist, optic.pupilSize,
        dirCos[0], dirCos[1], -dirCos[2],
        nx, wavelength, 1.0, optic.inMedium
    )

    if sphereRadius is None:
        sphereRadius = optic.sphereRadius

    outCoordSys = batoid.CoordSys()
    optic.traceInPlace(rays, outCoordSys=outCoordSys)
    w = np.where(1-rays.vignetted)[0]
    point = np.mean(rays.r[w], axis=0)

    # We want to place the vertex of the reference sphere one radius length away from the
    # intersection point.  So transform our rays into that coordinate system.
    transform = batoid.CoordTransform(
            outCoordSys, batoid.CoordSys(point+np.array([0,0,sphereRadius])))
    transform.applyForwardInPlace(rays)

    sphere = batoid.Sphere(-sphereRadius)
    sphere.intersectInPlace(rays)

    w = np.where(1-rays.vignetted)[0]
    # Should potentially try to make the reference time w.r.t. the chief ray instead of the mean
    # of the good (unvignetted) rays.
    t0 = np.mean(rays.t[w])

    arr = np.ma.masked_array((t0-rays.t)/wavelength, mask=rays.vignetted).reshape(nx, nx)
    primitiveVectors = np.vstack([[optic.pupilSize/nx, 0], [0, optic.pupilSize/nx]])
    return batoid.Lattice(arr, primitiveVectors)
Пример #19
0
def test_intersect():
    import random
    random.seed(577)
    for i in range(100):
        R = random.gauss(10.0, 0.1)
        sphere = batoid.Sphere(R)
        for j in range(10):
            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, -1000), (0, 0, 1), 0)
            r = sphere.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], sphere.sag(x, y), rtol=0, atol=1e-9)

    # Check normal for R=0 paraboloid (a plane)
    sphere = batoid.Sphere(0.0)
    np.testing.assert_array_equal(sphere.normal(0.1,0.1), [0,0,1])
Пример #20
0
def test_reflect():
    rng = np.random.default_rng(577)
    for i in range(1000):
        R = rng.uniform(1.0, 2.0)
        sphere = batoid.Sphere(R)

        reflectivity = rng.uniform(0, 1)
        transmissivity = rng.uniform(0, 1)
        coating = batoid.SimpleCoating(reflectivity, transmissivity)

        rv = batoid.RayVector(0, 0, 10, 0, 0, -1, 0, 500e-9, 1.0)

        sphere.reflect(rv, coating=coating)

        assert (rv.flux[0] == reflectivity)
Пример #21
0
def wavefront(optic,
              wavelength,
              theta_x=0,
              theta_y=0,
              nx=32,
              rays=None,
              saveRays=False,
              sphereRadius=None):
    if rays is None:
        xcos = np.sin(theta_x)
        ycos = np.sin(theta_y)
        zcos = -np.sqrt(1.0 - xcos**2 - ycos**2)

        rays = batoid.rayGrid(optic.dist, optic.pupilSize, xcos, ycos, zcos,
                              nx, wavelength, optic.inMedium)
    if saveRays:
        rays = batoid.RayVector(rays)
    if sphereRadius is None:
        sphereRadius = optic.sphereRadius

    outCoordSys = batoid.CoordSys()
    optic.traceInPlace(rays, outCoordSys=outCoordSys)
    goodRays = batoid._batoid.trimVignetted(rays)
    point = np.array(
        [np.mean(goodRays.x),
         np.mean(goodRays.y),
         np.mean(goodRays.z)])

    # We want to place the vertex of the reference sphere one radius length away from the
    # intersection point.  So transform our rays into that coordinate system.
    transform = batoid.CoordTransform(
        outCoordSys, batoid.CoordSys(point + np.array([0, 0, sphereRadius])))
    transform.applyForwardInPlace(rays)

    sphere = batoid.Sphere(-sphereRadius)
    sphere.intersectInPlace(rays)
    goodRays = batoid._batoid.trimVignetted(rays)
    # Should potentially try to make the reference time w.r.t. the chief ray instead of the mean
    # of the good (unvignetted) rays.
    t0 = np.mean(goodRays.t0)

    ts = rays.t0[:]
    isV = rays.isVignetted[:]
    ts -= t0
    ts /= wavelength
    wf = np.ma.masked_array(ts, mask=isV)
    return wf
Пример #22
0
def test_sphere():
    rng = np.random.default_rng(5772156)
    size = 1000
    for i in range(100):
        R = 1/rng.normal(0.0, 0.3)
        conic = 0.0
        quad = batoid.Quadric(R, conic)
        sphere = batoid.Sphere(R)
        x = rng.uniform(-0.7*R, 0.7*R, size=size)
        y = rng.uniform(-0.7*R, 0.7*R, size=size)
        np.testing.assert_allclose(
            quad.sag(x,y), sphere.sag(x, y),
            rtol=0, atol=1e-11
        )
        np.testing.assert_allclose(
            quad.normal(x,y), sphere.normal(x, y),
            rtol=0, atol=1e-11
        )
Пример #23
0
def test_refract():
    rng = np.random.default_rng(5772)
    for i in range(1000):
        R = rng.uniform(1.0, 2.0)
        sphere = batoid.Sphere(R)

        reflectivity = rng.uniform(0, 1)
        transmissivity = rng.uniform(0, 1)
        coating = batoid.SimpleCoating(reflectivity, transmissivity)

        m1 = batoid.ConstMedium(rng.uniform(1.1, 1.2))
        m2 = batoid.ConstMedium(rng.uniform(1.2, 1.3))

        rv = batoid.RayVector(0, 0, 10, 0, 0, -1, 0, 500e-9, 1.0)

        sphere.refract(rv, m1, m2, coating=coating)

        assert (rv.flux[0] == transmissivity)
Пример #24
0
def test_properties():
    rng = np.random.default_rng(5)
    for i in range(100):
        s1 = batoid.Sphere(rng.uniform(1, 3))
        s2 = batoid.Paraboloid(rng.uniform(1, 3))
        sum = batoid.Sum([s1, s2])
        do_pickle(sum)

        assert s1 is sum.surfaces[0]
        assert s2 is sum.surfaces[1]

        s3 = batoid.Quadric(rng.uniform(3, 5), rng.uniform(-0.1, 0.1))
        sum2 = batoid.Sum([s1, s2, s3])
        do_pickle(sum2)

        assert s1 is sum2.surfaces[0]
        assert s2 is sum2.surfaces[1]
        assert s3 is sum2.surfaces[2]
Пример #25
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(0.05, 0.01)
        sphere = batoid.Sphere(R)
        r1s = sphere.intersect(r0s.copy())
        r2s = batoid.RayVector([sphere.intersect(r0.copy()) for r0 in r0s])
        assert r1s == r2s
Пример #26
0
def test_properties():
    np.random.seed(5)
    for _ in range(100):
        s1 = batoid.Sphere(np.random.uniform(1, 3))
        s2 = batoid.Paraboloid(np.random.uniform(1, 3))
        sum = batoid.Sum([s1, s2])
        do_pickle(sum)

        assert s1 is sum.surfaces[0]
        assert s2 is sum.surfaces[1]

        s3 = batoid.Quadric(np.random.uniform(3, 5), np.random.uniform(-0.1, 0.1))
        sum2 = batoid.Sum([s1, s2, s3])
        do_pickle(sum2)

        assert s1 is sum2.surfaces[0]
        assert s2 is sum2.surfaces[1]
        assert s3 is sum2.surfaces[2]

        do_pickle(sum)
Пример #27
0
def test_sag():
    import random
    random.seed(57)
    for i in range(100):
        R = random.gauss(4.2, 0.3)
        sphere = batoid.Sphere(R)
        for j in range(10):
            x = random.uniform(-0.7*R, 0.7*R)
            y = random.uniform(-0.7*R, 0.7*R)
            result = sphere.sag(x, y)
            np.testing.assert_allclose(result, R*(1-math.sqrt(1.0-(x*x + y*y)/R/R)))
            # Check that it returned a scalar float and not an array
            assert isinstance(result, float)
        # Check vectorization
        x = np.random.uniform(-0.7*R, 0.7*R, size=(10, 10))
        y = np.random.uniform(-0.7*R, 0.7*R, size=(10, 10))
        np.testing.assert_allclose(sphere.sag(x, y), R*(1-np.sqrt(1.0-(x*x + y*y)/R/R)))
        # Make sure non-unit stride arrays also work
        np.testing.assert_allclose(
            sphere.sag(x[::5,::2], y[::5,::2]),
            (R*(1-np.sqrt(1.0-(x*x + y*y)/R/R)))[::5, ::2]
        )
Пример #28
0
def test_add_plane():
    rng = np.random.default_rng(5772156)
    for _ in range(100):
        # Adding a plane should have zero effect on sag or normal vector
        s1 = batoid.Sphere(rng.uniform(1, 3))
        s2 = batoid.Plane()
        sum = batoid.Sum([s1, s2])

        x = rng.normal(size=5000)
        y = rng.normal(size=5000)

        np.testing.assert_allclose(sum.sag(x, y),
                                   s1.sag(x, y),
                                   rtol=0,
                                   atol=1e-12)

        np.testing.assert_allclose(
            sum.normal(x, y),
            s1.normal(x, y),
            rtol=0,
            atol=1e-12,
        )
Пример #29
0
def test_intersect():
    rng = np.random.default_rng(5772)
    size = 10_000
    for _ in range(100):
        s1 = batoid.Sphere(1. / rng.normal(0., 0.2))
        s2 = batoid.Paraboloid(rng.uniform(1, 3))
        sum = batoid.Sum([s1, s2])
        sumCoordSys = batoid.CoordSys(origin=[0, 0, -1])
        x = rng.uniform(-1, 1, size=size)
        y = rng.uniform(-1, 1, 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(sum, rv.copy(), sumCoordSys)
        assert rv2.coordSys == sumCoordSys

        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,
                                   sum.sag(x, y) - 1,
                                   rtol=0,
                                   atol=1e-12)

        # Check default intersect coordTransform
        rv2 = rv.copy().toCoordSys(sumCoordSys)
        batoid.intersect(sum, rv2)
        assert rv2.coordSys == sumCoordSys
        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,
                                   sum.sag(x, y) - 1,
                                   rtol=0,
                                   atol=1e-12)
Пример #30
0
def test_intersect():
    rng = np.random.default_rng(5772)
    size = 10_000
    for i in range(100):
        R = 1. / rng.normal(0.0, 0.3)
        sphereCoordSys = batoid.CoordSys(origin=[0, 0, -1])
        sphere = batoid.Sphere(R)
        x = rng.uniform(-0.3 * abs(R), 0.3 * abs(R), size=size)
        y = rng.uniform(-0.3 * abs(R), 0.3 * abs(R), size=size)
        z = np.full_like(x, -2 * abs(R))
        # 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, -2 * abs(R))
        rv2 = batoid.intersect(sphere, rv.copy(), sphereCoordSys)
        assert rv2.coordSys == sphereCoordSys

        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,
                                   sphere.sag(x, y) - 1,
                                   rtol=0,
                                   atol=1e-9)

        # Check default intersect coordTransform
        rv2 = rv.copy().toCoordSys(sphereCoordSys)
        batoid.intersect(sphere, rv2)
        assert rv2.coordSys == sphereCoordSys
        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,
                                   sphere.sag(x, y) - 1,
                                   rtol=0,
                                   atol=1e-9)