Esempio n. 1
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)
Esempio n. 2
0
def test_propagate():
    rng = np.random.default_rng(577)
    size = 10_000

    x = rng.uniform(-1, 1, size=size)
    y = rng.uniform(-1, 1, size=size)
    z = rng.uniform(-0.1, 0.1, size=size)
    vx = rng.uniform(-0.05, 0.05, size=size)
    vy = rng.uniform(-0.05, 0.05, size=size)
    vz = np.sqrt(1.0 - vx * vx - vy * vy)
    # Try with default t=0 first
    rv = batoid.RayVector(x, y, z, vx, vy, vz)

    for t1 in [0.0, 1.0, -1.1, 2.5]:
        rvcopy = rv.copy()
        r1 = rv.positionAtTime(t1)
        rvcopy.propagate(t1)
        np.testing.assert_equal(rvcopy.r, r1)
        np.testing.assert_equal(rvcopy.v, rv.v)
        np.testing.assert_equal(rvcopy.t, t1)

    # Now add some random t's
    t = rng.uniform(-1.0, 1.0, size=size)
    rv = batoid.RayVector(x, y, z, vx, vy, vz, t)
    for t1 in [0.0, 1.0, -1.1, 2.5]:
        rvcopy = rv.copy()
        r1 = rv.positionAtTime(t1)
        rvcopy.propagate(t1)
        np.testing.assert_equal(rvcopy.r, r1)
        np.testing.assert_equal(rvcopy.v, rv.v)
        np.testing.assert_equal(rvcopy.t, t1)
Esempio n. 3
0
def test_intersect_vectorized():
    np.random.seed(57721)
    jmaxmax = 50
    r0s = [
        batoid.Ray([
            np.random.normal(0.0, 0.1),
            np.random.normal(0.0, 0.1),
            np.random.normal(10.0, 0.1)
        ], [
            np.random.normal(0.0, 0.1),
            np.random.normal(0.0, 0.1),
            np.random.normal(-1.0, 0.1)
        ], np.random.normal(0.0, 0.1)) for i in range(100)
    ]
    r0s = batoid.RayVector(r0s)

    for i in range(100):
        jmax = np.random.randint(1, jmaxmax)
        coef = np.random.normal(size=jmax + 1) * 1e-3
        R_outer = np.random.uniform(0.5, 5.0)
        R_inner = np.random.uniform(0.0, 0.8 * R_outer)
        zernike = batoid.Zernike(coef, R_outer=R_outer, R_inner=R_inner)

        r1s = zernike.intersect(r0s)
        r2s = batoid.RayVector([zernike.intersect(r0) for r0 in r0s])
        assert r1s == r2s
Esempio n. 4
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
Esempio n. 5
0
def test_ObscCircle():
    rng = np.random.default_rng(5)
    size = 10_000

    for i in range(100):
        cx = rng.normal(0.0, 1.0)
        cy = rng.normal(0.0, 1.0)
        r = rng.uniform(0.5, 1.5)
        obsc = batoid.ObscCircle(r, cx, cy)

        for i in range(100):
            x = rng.normal(0.0, 1.0)
            y = rng.normal(0.0, 1.0)
            assert obsc.contains(x, y) == (np.hypot(x - cx, y - cy) <= r)

        x = rng.normal(0.0, 1.0, size=size)
        y = rng.normal(0.0, 1.0, size=size)
        np.testing.assert_array_equal(obsc.contains(x, y),
                                      np.hypot(x - cx, y - cy) <= r)

        do_pickle(obsc)

        rv = batoid.RayVector(x, y, 0.0, 0.0, 0.0, 0.0)
        batoid.obscure(obsc, rv)
        np.testing.assert_array_equal(obsc.contains(x, y), rv.vignetted)

        # Check method syntax too
        rv = batoid.RayVector(x, y, 0.0, 0.0, 0.0, 0.0)
        obsc.obscure(rv)
        np.testing.assert_array_equal(obsc.contains(x, y), rv.vignetted)
Esempio n. 6
0
def test_ne():
    objs = [
        batoid.Ray((0, 0, 0), (0, 0, 0)),
        batoid.Ray((0, 0, 0), (0, 0, 0), coordSys=batoid.CoordSys((0, 0, 1))),
        batoid.Ray((0, 0, 1), (0, 0, 0)),
        batoid.Ray((0, 1, 0), (0, 0, 0)),
        batoid.Ray((0, 0, 0), (0, 0, 0), t=1),
        batoid.Ray((0, 0, 0), (0, 0, 0), wavelength=500e-9),
        batoid.Ray((0, 0, 0), (0, 0, 0), wavelength=500e-9, flux=1.2),
        batoid.Ray((0, 0, 0), (0, 0, 0), vignetted=True),
        batoid.Ray(failed=True), (0, 0, 0),
        batoid.RayVector([
            batoid.Ray((0, 0, 1), (0, 0, 0)),
            batoid.Ray((0, 0, 0), (0, 0, 0))
        ]),
        batoid.RayVector([
            batoid.Ray((0, 0, 1), (0, 0, 0),
                       coordSys=batoid.CoordSys((0, 0, 1))),
            batoid.Ray((0, 0, 0), (0, 0, 0),
                       coordSys=batoid.CoordSys((0, 0, 1)))
        ]),
        batoid.RayVector([
            batoid.Ray((0, 0, 0), (0, 0, 0)),
            batoid.Ray((0, 0, 1), (0, 0, 0))
        ]),
        batoid.RayVector([batoid.Ray((0, 0, 0), (0, 0, 0))])
    ]
    all_obj_diff(objs)
Esempio n. 7
0
def test_fail():
    quad = batoid.Quadric(1.0, 0.0)
    rv = batoid.RayVector(0, 10, 0, 0, 0, -1)  # Too far to side
    rv2 = batoid.intersect(quad, 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(quad, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([False]))
Esempio n. 8
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]))
Esempio n. 9
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]))
Esempio n. 10
0
def test_fail():
    zernike = batoid.Zernike([0,0,0,0,1])  # basically a paraboloid
    rv = batoid.RayVector(0, 0, -10, 0, 0.99, np.sqrt(1-0.99**2))  # Too shallow
    rv2 = batoid.intersect(zernike, 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(zernike, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([False]))
Esempio n. 11
0
def test_equals():
    import time
    rng = np.random.default_rng(577215)
    size = 10_000

    x = rng.uniform(-1, 1, size=size)
    y = rng.uniform(-1, 1, size=size)
    z = rng.uniform(-0.1, 0.1, size=size)
    vx = rng.uniform(-0.05, 0.05, size=size)
    vy = rng.uniform(-0.05, 0.05, size=size)
    vz = np.sqrt(1.0 - vx * vx - vy * vy)
    t = rng.uniform(-1.0, 1.0, size=size)
    wavelength = rng.uniform(300e-9, 1100e-9, size=size)
    flux = rng.uniform(0.9, 1.1, size=size)
    vignetted = rng.choice([True, False], size=size)
    failed = rng.choice([True, False], size=size)

    args = x, y, z, vx, vy, vz, t, wavelength, flux, vignetted, failed
    rv = batoid.RayVector(*args)
    rv2 = rv.copy()
    assert rv == rv2

    for i in range(len(args)):
        newargs = [args[i].copy() for i in range(len(args))]
        ai = newargs[i]
        if ai.dtype == float:
            ai[0] = 1.2 + ai[0] * 3.45
        elif ai.dtype == bool:
            ai[0] = not ai[0]
        # else panic!
        rv2 = batoid.RayVector(*newargs)
        assert rv != rv2

    # Repeat, but force comparison on device
    rv2 = rv.copy()
    rv._rv.x.syncToDevice()
    rv._rv.y.syncToDevice()
    rv._rv.z.syncToDevice()
    rv._rv.vx.syncToDevice()
    rv._rv.vy.syncToDevice()
    rv._rv.vz.syncToDevice()
    rv._rv.t.syncToDevice()
    rv._rv.wavelength.syncToDevice()
    rv._rv.flux.syncToDevice()
    rv._rv.vignetted.syncToDevice()
    rv._rv.failed.syncToDevice()
    assert rv == rv2
    for i in range(len(args)):
        newargs = [args[i].copy() for i in range(len(args))]
        ai = newargs[i]
        if ai.dtype == float:
            ai[0] = 1.2 + ai[0] * 3.45
        elif ai.dtype == bool:
            ai[0] = not ai[0]
        # else panic!
        rv2 = batoid.RayVector(*newargs)
        assert rv != rv2
Esempio n. 12
0
def test_fail():
    para = batoid.Paraboloid(1.0)
    rv = batoid.RayVector(0, 0, -10, 0, 0.99,
                          np.sqrt(1 - 0.99**2))  # Too shallow
    rv2 = batoid.intersect(para, 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(para, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([False]))
Esempio n. 13
0
def test_refraction_chromatic():
    import random
    random.seed(577215664)
    wavelength1 = 500e-9
    wavelength2 = 600e-9
    flux = 1.0

    plane = batoid.Plane()
    filename = os.path.join(batoid.datadir, "media", "silica_dispersion.txt")
    wave, n = np.genfromtxt(filename).T
    wave *= 1e-6  # micron -> meters
    table = batoid.Table(wave, n, batoid.Table.Interpolant.linear)
    silica = batoid.TableMedium(table)
    air = batoid.Air()

    thx, thy = 0.001, 0.0001
    dirCos = batoid.utils.gnomonicToDirCos(thx, thy)
    rv1 = batoid.rayGrid(10.0, 1., dirCos[0], dirCos[1], -dirCos[2], 2,
                         wavelength1, flux, silica)
    rv2 = batoid.rayGrid(10.0, 1., dirCos[0], dirCos[1], -dirCos[2], 2,
                         wavelength2, flux, silica)
    rays = []
    for ray in rv1:
        rays.append(ray)
    for ray in rv2:
        rays.append(ray)
    rvCombined = batoid.RayVector(rays)

    rv1r = plane.refract(rv1, silica, air)
    rv2r = plane.refract(rv2, silica, air)
    assert rv1r != rv2r
    rays = []
    for ray in rv1r:
        rays.append(ray)
    for ray in rv2r:
        rays.append(ray)
    rvrCombined1 = batoid.RayVector(rays)

    rvrCombined2 = plane.refract(rvCombined, silica, air)

    assert rvrCombined1 == rvrCombined2

    # Check in-place
    plane.refractInPlace(rv1, silica, air)
    plane.refractInPlace(rv2, silica, air)
    assert rv1 != rv2
    plane.refractInPlace(rvCombined, silica, air)
    rays = []
    for ray in rv1:
        rays.append(ray)
    for ray in rv2:
        rays.append(ray)
    rvCombined2 = batoid.RayVector(rays)

    assert rvCombined == rvCombined2
Esempio n. 14
0
def test_fail():
    plane = batoid.Plane()

    # Only fail if vz == 0
    rv = batoid.RayVector(0, 0, 0, 0, 1, 0)
    rv2 = batoid.intersect(plane, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([True]))

    # Otherwise, succeeds
    rv = batoid.RayVector(0, 0, 0, 0, 0, -1)
    rv2 = batoid.intersect(plane, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([False]))
Esempio n. 15
0
def test_fail():
    tilted = batoid.Tilted(0, 0)

    # Fail if vz == 0
    rv = batoid.RayVector(0, 0, 0, 0, 1, 0)
    rv2 = batoid.intersect(tilted, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([True]))

    # Otherwise, succeeds
    rv = batoid.RayVector(0, 0, 0, 0, 0, -1)
    rv2 = batoid.intersect(tilted, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([False]))
Esempio n. 16
0
def test_fail():
    xs = np.linspace(-1, 1, 10)
    ys = np.linspace(-1, 1, 10)
    def f(x, y):
        return x+y
    zs = f(*np.meshgrid(xs, ys))
    bc = batoid.Bicubic(xs, ys, zs)

    rv = batoid.RayVector(0, 10, 0, 0, 0, -1)  # Too far to side
    rv2 = batoid.intersect(bc, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([True]))
    # This one passes
    rv = batoid.RayVector(0, 0, 0, 0, 0, -1)
    rv2 = batoid.intersect(bc, rv.copy())
    np.testing.assert_equal(rv2.failed, np.array([False]))
Esempio n. 17
0
def test_traceReverse():
    if __name__ == '__main__':
        nside = 128
    else:
        nside = 32

    fn = os.path.join(batoid.datadir, "HSC", "HSC.yaml")
    config = yaml.load(open(fn))
    telescope = batoid.parse.parse_optic(config['opticalSystem'])

    init_rays = batoid.rayGrid(20, 12.0, 0.005, 0.005, -1.0, nside, 500e-9,
                               1.0, batoid.ConstMedium(1.0))
    forward_rays, _ = telescope.trace(init_rays, outCoordSys=batoid.CoordSys())

    # Now, turn the result rays around and trace backwards
    forward_rays = forward_rays.propagatedToTime(40.0)
    reverse_rays = batoid.RayVector(
        [batoid.Ray(r.r, -r.v, -r.t, r.wavelength) for r in forward_rays])

    final_rays, _ = telescope.traceReverse(reverse_rays,
                                           outCoordSys=batoid.CoordSys())
    # propagate all the way to t=0
    final_rays = final_rays.propagatedToTime(0.0)

    w = np.where(np.logical_not(final_rays.vignetted))[0]
    for idx in w:
        np.testing.assert_allclose(init_rays[idx].x, final_rays[idx].x)
        np.testing.assert_allclose(init_rays[idx].y, final_rays[idx].y)
        np.testing.assert_allclose(init_rays[idx].z, final_rays[idx].z)
        np.testing.assert_allclose(init_rays[idx].vx, -final_rays[idx].vx)
        np.testing.assert_allclose(init_rays[idx].vy, -final_rays[idx].vy)
        np.testing.assert_allclose(init_rays[idx].vz, -final_rays[idx].vz)
        np.testing.assert_allclose(final_rays[idx].t, 0)
Esempio n. 18
0
def test_optic():
    if __name__ == '__main__':
        nside = 128
    else:
        nside = 32

    rays = batoid.rayGrid(20, 12.0, 0.005, 0.005, -1.0, nside, 500e-9, 1.0,
                          batoid.ConstMedium(1.0))

    nrays = len(rays)
    print("Tracing {} rays.".format(nrays))
    t_fast = 0.0
    t_slow = 0.0

    fn = os.path.join(batoid.datadir, "HSC", "HSC.yaml")
    config = yaml.load(open(fn))
    telescope = batoid.parse.parse_optic(config['opticalSystem'])
    do_pickle(telescope)

    t0 = time.time()

    rays_fast, _ = telescope.trace(rays)
    t1 = time.time()
    rays_slow = batoid.RayVector([telescope.trace(r)[0] for r in rays])
    t2 = time.time()

    assert rays_fast == rays_slow
    t_fast = t1 - t0
    t_slow = t2 - t1
    print("Fast trace: {:5.3f} s".format(t_fast))
    print("            {} rays per second".format(int(nrays / t_fast)))
    print("Slow trace: {:5.3f} s".format(t_slow))
    print("            {} rays per second".format(int(nrays / t_slow)))
Esempio n. 19
0
def test_refract():
    rng = np.random.default_rng(57721)
    size = 10_000
    tanx = rng.uniform(-0.1, 0.1)
    tany = rng.uniform(-0.1, 0.1)
    plane = batoid.Tilted(tanx, tany)
    m0 = batoid.ConstMedium(rng.normal(1.2, 0.01))
    m1 = batoid.ConstMedium(rng.normal(1.3, 0.01))
    x = rng.normal(0.0, 1.0, size=size)
    y = rng.normal(0.0, 1.0, size=size)
    z = np.full_like(x, -100.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(plane, rv.copy(), m0, m1)
    rvr2 = plane.refract(rv.copy(), m0, m1)
    rays_allclose(rvr, rvr2)
    # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
    normal = plane.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)
Esempio n. 20
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)
Esempio n. 21
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)
Esempio n. 22
0
def test_sumAmplitude():
    import time
    rng = np.random.default_rng(57721)
    size = 10_000

    for n in [1.0, 1.3]:
        x = rng.uniform(-1, 1, size=size)
        y = rng.uniform(-1, 1, size=size)
        z = rng.uniform(-0.1, 0.1, size=size)
        vx = rng.uniform(-0.05, 0.05, size=size)
        vy = rng.uniform(-0.05, 0.05, size=size)
        vz = np.sqrt(1.0/(n*n) - vx*vx - vy*vy)
        t = rng.uniform(-1.0, 1.0, size=size)
        wavelength = rng.uniform(300e-9, 1100e-9, size=size)
        rv = batoid.RayVector(x, y, z, vx, vy, vz, t, wavelength)
        satime = 0
        atime = 0
        for r1, t1 in [
            ((0, 0, 0), 0),
            ((0, 1, 2), 3),
            ((-1, 2, 4), -1),
            ((0, 1, -4), -2)
        ]:
            at0 = time.time()
            s1 = rv.sumAmplitude(r1, t1)
            at1 = time.time()
            s2 = np.sum(rv.amplitude(r1, t1))
            at2 = time.time()

            np.testing.assert_allclose(s1, s2, rtol=0, atol=1e-11)
            satime += at1-at0
            atime += at2-at1
Esempio n. 23
0
def test_reflect():
    rng = np.random.default_rng(5772)
    size = 10_000
    tanx = rng.uniform(-0.1, 0.1)
    tany = rng.uniform(-0.1, 0.1)
    plane = batoid.Tilted(tanx, tany)
    x = rng.normal(0.0, 1.0, size=size)
    y = rng.normal(0.0, 1.0, size=size)
    z = np.full_like(x, -100.0)
    vx = rng.uniform(-1e-5, 1e-5, size=size)
    vy = rng.uniform(-1e-5, 1e-5, size=size)
    vz = np.ones_like(x)
    rv = batoid.RayVector(x, y, z, vx, vy, vz)
    rvr = batoid.reflect(plane, rv.copy())
    rvr2 = plane.reflect(rv.copy())
    rays_allclose(rvr, rvr2)
    # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
    normal = plane.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)
Esempio n. 24
0
def test_traceReverse():
    if __name__ == '__main__':
        nside = 128
    else:
        nside = 32

    telescope = batoid.Optic.fromYaml("HSC.yaml")

    init_rays = batoid.rayGrid(20, 12.0, 0.005, 0.005, -1.0, nside, 500e-9, 1.0, batoid.ConstMedium(1.0))
    forward_rays = telescope.trace(init_rays)

    # Now, turn the result rays around and trace backwards
    forward_rays = forward_rays.propagatedToTime(40.0)
    reverse_rays = batoid.RayVector(
        [batoid.Ray(r.r, -r.v, -r.t, r.wavelength) for r in forward_rays]
    )

    final_rays = telescope.traceReverse(reverse_rays)
    # propagate all the way to t=0
    final_rays = final_rays.propagatedToTime(0.0)
    final_rays.toCoordSysInPlace(batoid.globalCoordSys)

    w = np.where(np.logical_not(final_rays.vignetted))[0]
    for idx in w:
        np.testing.assert_allclose(init_rays[idx].x, final_rays[idx].x)
        np.testing.assert_allclose(init_rays[idx].y, final_rays[idx].y)
        np.testing.assert_allclose(init_rays[idx].z, final_rays[idx].z)
        np.testing.assert_allclose(init_rays[idx].vx, -final_rays[idx].vx)
        np.testing.assert_allclose(init_rays[idx].vy, -final_rays[idx].vy)
        np.testing.assert_allclose(init_rays[idx].vz, -final_rays[idx].vz)
        np.testing.assert_allclose(final_rays[idx].t, 0)
Esempio n. 25
0
def test_refract():
    rng = np.random.default_rng(577215)
    size = 10_000
    for i in range(100):
        R = 1. / rng.normal(0.0, 0.3)
        conic = rng.uniform(-2.0, 1.0)
        quad = batoid.Quadric(R, conic)
        m0 = batoid.ConstMedium(rng.normal(1.2, 0.01))
        m1 = batoid.ConstMedium(rng.normal(1.3, 0.01))
        lim = min(0.7 * abs(R) / np.sqrt(1 + conic) if conic > -1 else 10, 10)
        x = rng.uniform(-lim, lim, size=size)
        y = rng.uniform(-lim, lim, size=size)
        z = np.full_like(x, -100.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(quad, rv.copy(), m0, m1)
        rvr2 = quad.refract(rv.copy(), m0, m1)
        rays_allclose(rvr, rvr2)
        # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
        normal = quad.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)
Esempio n. 26
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)
        conic = rng.uniform(-2.0, 1.0)
        quad = batoid.Quadric(R, conic)
        lim = min(0.7 * abs(R) / np.sqrt(1 + conic) if conic > -1 else 10, 10)
        x = rng.uniform(-lim, lim, size=size)
        y = rng.uniform(-lim, lim, size=size)
        z = np.full_like(x, -100.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(quad, rv.copy())
        rvr2 = quad.reflect(rv.copy())
        rays_allclose(rvr, rvr2)
        # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
        normal = quad.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)
Esempio n. 27
0
def test_intersect():
    rng = np.random.default_rng(577)
    tanx = rng.uniform(-0.1, 0.1)
    tany = rng.uniform(-0.1, 0.1)
    size = 10_000
    tiltedCoordSys = batoid.CoordSys(origin=[0, 0, -1])
    tilted = batoid.Tilted(tanx, tany)
    x = rng.normal(0.0, 1.0, size=size)
    y = rng.normal(0.0, 1.0, size=size)
    z = np.full_like(x, -100.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, -100.0)
    rv2 = batoid.intersect(tilted, rv.copy(), tiltedCoordSys)
    assert rv2.coordSys == tiltedCoordSys
    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, tilted.sag(x, y) - 1, rtol=0, atol=1e-12)

    # Check default intersect coordTransform
    rv2 = rv.copy().toCoordSys(tiltedCoordSys)
    batoid.intersect(tilted, rv2)
    assert rv2.coordSys == tiltedCoordSys
    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, tilted.sag(x, y) - 1, rtol=0, atol=1e-12)
Esempio n. 28
0
def test_ObscAnnulus():
    rng = np.random.default_rng(57)
    size = 10_000

    for i in range(100):
        cx = rng.normal(0.0, 1.0)
        cy = rng.normal(0.0, 1.0)
        inner = rng.uniform(0.5, 1.5)
        outer = rng.uniform(1.6, 1.9)
        obsc = batoid.ObscAnnulus(inner, outer, cx, cy)

        for i in range(100):
            x = rng.normal(0.0, 1.0)
            y = rng.normal(0.0, 1.0)
            assert obsc.contains(
                x, y) == (inner <= np.hypot(x - cx, y - cy) < outer)

        x = rng.normal(0.0, 1.0, size=size)
        y = rng.normal(0.0, 1.0, size=size)
        r = np.hypot(x - cx, y - cy)
        np.testing.assert_array_equal(obsc.contains(x, y),
                                      (inner <= r) & (r < outer))

        do_pickle(obsc)

        rv = batoid.RayVector(x, y, 0.0, 0.0, 0.0, 0.0)
        batoid.obscure(obsc, rv)
        np.testing.assert_array_equal(obsc.contains(x, y), rv.vignetted)
Esempio n. 29
0
def test_optic():
    if __name__ == '__main__':
        nside = 128
    else:
        nside = 32

    rays = batoid.rayGrid(20, 12.0, 0.005, 0.005, -1.0, nside, 500e-9, 1.0, batoid.ConstMedium(1.0))

    nrays = len(rays)
    print("Tracing {} rays.".format(nrays))
    t_fast = 0.0
    t_slow = 0.0

    telescope = batoid.Optic.fromYaml("HSC.yaml")
    do_pickle(telescope)

    t0 = time.time()

    rays_fast = telescope.trace(rays)
    t1 = time.time()
    rays_slow = batoid.RayVector([telescope.trace(r) for r in rays])
    t2 = time.time()

    assert rays_fast == rays_slow
    t_fast = t1 - t0
    t_slow = t2 - t1
    print("Fast trace: {:5.3f} s".format(t_fast))
    print("            {} rays per second".format(int(nrays/t_fast)))
    print("Slow trace: {:5.3f} s".format(t_slow))
    print("            {} rays per second".format(int(nrays/t_slow)))
Esempio n. 30
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)  # negative allowed
        para = batoid.Paraboloid(R)
        x = rng.normal(0.0, 1.0, size=size)
        y = rng.normal(0.0, 1.0, size=size)
        z = np.full_like(x, -100.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(para, rv.copy())
        rvr2 = para.reflect(rv.copy())
        rays_allclose(rvr, rvr2)
        # print(f"{np.sum(rvr.failed)/len(rvr)*100:.2f}% failed")
        normal = para.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)