示例#1
0
def test_circularGrid():
    dist = 10.0
    outer = 4.1
    inner = 0.5
    xcos = 0.1
    ycos = 0.2
    zcos = -np.sqrt(1.0 - xcos**2 - ycos**2)
    nradii = 5
    naz = 50
    wavelength = 500e-9
    flux = 1.2
    medium = batoid.ConstMedium(1.2)

    rays = batoid.circularGrid(dist, outer, inner, xcos, ycos, zcos, nradii,
                               naz, wavelength, flux, medium)
    assert rays.monochromatic == True
    # Check that all rays are perpendicular to v
    ray0 = rays[0]
    for ray in rays:
        dr = ray.r - ray0.r
        dp = np.dot(dr, ray0.v)
        np.testing.assert_allclose(dp, 0.0, atol=1e-14, rtol=0.0)
        np.testing.assert_allclose(ray.wavelength, wavelength)
        np.testing.assert_allclose(ray.flux, flux)
        np.testing.assert_allclose(np.linalg.norm(ray.v), 1. / 1.2)
        np.testing.assert_allclose(ray.v[0] * 1.2, xcos)
        np.testing.assert_allclose(ray.v[1] * 1.2, ycos)
示例#2
0
def test_sum_bicubic():
    import os
    import yaml

    fn = os.path.join(batoid.datadir, "LSST", "LSST_i.yaml")
    config = yaml.safe_load(open(fn))
    telescope = batoid.parse.parse_optic(config['opticalSystem'])
    xcos, ycos, zcos = batoid.utils.gnomonicToDirCos(np.deg2rad(0.8),
                                                     np.deg2rad(0.8))
    rays = batoid.circularGrid(
        telescope.dist, telescope.pupilSize / 2,
        telescope.pupilSize * telescope.pupilObscuration / 2, xcos, ycos,
        -zcos, 50, 50, 750e-9, 1.0, telescope.inMedium)
    out, _ = telescope.trace(rays)

    m2 = telescope.itemDict['LSST.M2']

    xs = np.linspace(-m2.outRadius, m2.outRadius, 200)
    ys = xs
    zs = np.zeros((200, 200), dtype=float)
    bicubic = batoid.Bicubic(xs, ys, zs)

    m2.surface = batoid.Sum([m2.surface, bicubic])
    out2, _ = telescope.trace(rays)

    # Don't expect exact equality, but should be very similar
    assert rays_allclose(out, out2, atol=1e-13)
示例#3
0
def test_sum_bicubic():
    telescope = batoid.Optic.fromYaml("LSST_i.yaml")
    xcos, ycos, zcos = batoid.utils.gnomonicToDirCos(
        np.deg2rad(0.8), np.deg2rad(0.8)
    )
    rays = batoid.circularGrid(
        telescope.backDist,
        telescope.pupilSize/2,
        telescope.pupilSize*telescope.pupilObscuration/2,
        xcos, ycos, -zcos,
        50, 50, 750e-9, 1.0, telescope.inMedium
    )
    out = telescope.trace(rays)

    m2 = telescope['LSST.M2']

    xs = np.linspace(-m2.outRadius, m2.outRadius, 200)
    ys = xs
    zs = np.zeros((200, 200), dtype=float)
    bicubic = batoid.Bicubic(xs, ys, zs)

    m2.surface = batoid.Sum([m2.surface, bicubic])
    out2 = telescope.trace(rays)

    # Don't expect exact equality, but should be very similar
    assert rays_allclose(out, out2, atol=1e-13)
示例#4
0
def test_decam_psf():
    # Just testing that doesn't crash for the moment
    fn = os.path.join(batoid.datadir, "DECam", "DECam.yaml")
    config = yaml.load(open(fn))
    telescope = batoid.parse.parse_optic(config['opticalSystem'])

    stampSize = 1.0  # arcsec
    nx = 64
    focalLength = 10.0  # guess

    if __name__ == '__main__':
        thetas = [0.0, 1800.0, 3960.0]  # arcsec
    else:
        thetas = [3960.0]
    for theta in thetas:
        print(theta / 3600.0)
        dirCos = batoid.utils.gnomicToDirCos(0.0, theta / 206265)
        rays = batoid.circularGrid(10.0, 1.95, 0.5, dirCos[0], dirCos[1],
                                   -dirCos[2], 10, 100, 620e-9, 1.0,
                                   batoid.Air())
        telescope.traceInPlace(rays)
        rays.trimVignettedInPlace()
        xs = rays.x - np.mean(rays.x)
        ys = rays.y - np.mean(rays.y)

        xs *= 206265 / focalLength  # meters to arcsec
        ys *= 206265 / focalLength

        # Need to add half-pixel offset
        xs += stampSize / nx / 2
        ys += stampSize / nx / 2

        dx = stampSize / nx * focalLength / 206265  # meters

        psf = batoid.huygensPSF(telescope,
                                0.0,
                                theta / 206265,
                                620e-9,
                                nx=nx,
                                dx=dx,
                                dy=dx)

        if __name__ == '__main__':
            import matplotlib.pyplot as plt
            fig = plt.figure(figsize=(12, 8))
            ax = fig.add_subplot(111)
            ax.imshow(psf.array, extent=np.r_[-1, 1, -1, 1] * stampSize / 2)
            ax.scatter(xs, ys, s=5, c='r', alpha=0.5)
            ax.set_title("DECam PSF field={:5.2f}".format(theta / 3600.0))
            ax.set_xlabel("arcsec")
            ax.set_ylabel("arcsec")

            fig.tight_layout()
            plt.show()
示例#5
0
def test_hsc_psf():
    # Just testing that doesn't crash for the moment
    telescope = batoid.Optic.fromYaml("HSC.yaml")

    stampSize = 0.75  # arcsec
    nx = 64
    focalLength = 15.0  # guess

    if __name__ == '__main__':
        thetas = [0.0, 1350.0, 2700.0]  # arcsec
    else:
        thetas = [2700.0]
    for theta in thetas:
        print(theta / 3600.0)
        dirCos = batoid.utils.gnomonicToDirCos(0.0, theta / 206265)
        rays = batoid.circularGrid(20.0, 4.1, 0.9, dirCos[0], dirCos[1],
                                   dirCos[2], 10, 100, 620e-9, 1.0,
                                   batoid.ConstMedium(1.0))
        telescope.traceInPlace(rays)
        rays.trimVignettedInPlace()
        xs = rays.x - np.mean(rays.x)
        ys = rays.y - np.mean(rays.y)

        xs *= 206265 / focalLength  # meters to arcsec
        ys *= 206265 / focalLength

        # Need to add half-pixel offset
        xs += stampSize / nx / 2
        ys += stampSize / nx / 2

        dx = stampSize / nx * focalLength / 206265  # meters

        psf = batoid.huygensPSF(telescope,
                                0.0,
                                theta / 206265,
                                620e-9,
                                nx=nx,
                                dx=dx,
                                dy=dx)

        if __name__ == '__main__':
            import matplotlib.pyplot as plt
            fig = plt.figure(figsize=(12, 8))
            ax = fig.add_subplot(111)
            ax.imshow(psf.array, extent=np.r_[-1, 1, -1, 1] * stampSize / 2)
            ax.scatter(xs, ys, s=5, c='r', alpha=0.5)
            ax.set_title("HSC PSF field={:5.2f}".format(theta / 3600.0))
            ax.set_xlabel("arcsec")
            ax.set_ylabel("arcsec")

            fig.tight_layout()
            plt.show()
示例#6
0
fn = os.path.join(batoid.datadir, "HSC", "HSC.yaml")
factor = 0.168 / 1.5e-5 / 3600

# fn = os.path.join(batoid.datadir, "DECam", "DECam.yaml")
# factor = 0.27/1.5e-5/3600

config = yaml.load(open(fn))
telescope = batoid.parse.parse_optic(config['opticalSystem'])

angles = np.linspace(0.0, 1.0, 21, endpoint=True)
angles = [0.3]
for angle in angles:
    dirCos = batoid.utils.gnomicToDirCos(0.0, np.deg2rad(angle))

    rays = batoid.circularGrid(
        telescope.dist, telescope.pupilSize / 2,
        telescope.pupilSize * telescope.pupilObscuration / 2, dirCos[0],
        dirCos[1], -dirCos[2], 300, 900, 500e-9, 1.0, telescope.inMedium)

    rForward, rReverse, _, _ = telescope.traceSplit(rays,
                                                    minFlux=1e-4,
                                                    verbose=True)

    print(len(rays))
    print(np.sum(rays.flux))
    print(len(rForward))
    print(len(rReverse))
    print(np.sum(rForward.flux))
    print(np.sum(rReverse.flux))

    fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8, 8))
    ax.hexbin(rForward.x * factor,
示例#7
0
def parallel_trace_timing(nside=1024, nthread=None, minChunk=None):
    if nthread is not None:
        print("setting to nthread to {}".format(nthread))
        batoid._batoid.setNThread(nthread)
    print("Using {} threads".format(batoid._batoid.getNThread()))

    if minChunk is not None:
        print("setting to minChunk to {}".format(minChunk))
        batoid._batoid.setMinChunk(minChunk)
    print("Using minChunk of {}".format(batoid._batoid.getMinChunk()))

    # 0.3, 0.3 should be in bounds for current wide-field telescopes
    theta_x = np.deg2rad(0.3)
    theta_y = np.deg2rad(0.3)
    dirCos = np.array([theta_x, theta_y, -1.0])
    dirCos = batoid.utils.normalized(dirCos)
    rays = batoid.circularGrid(
        20, 4.2, 0.5,
        dirCos[0], dirCos[1], dirCos[2],
        nside, nside, 700e-9, 1.0, batoid.ConstMedium(1.0)
    )

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

    if args.lsst:
        fn = os.path.join(batoid.datadir, "LSST", "LSST_r.yaml")
        pm = 'LSST.M1'
    else:
        fn = os.path.join(batoid.datadir, "HSC", "HSC.yaml")
        pm = 'SubaruHSC.PM'
    config = yaml.load(open(fn))
    telescope = batoid.parse.parse_optic(config['opticalSystem'])

    # Optionally perturb the primary mirror using Zernike polynomial
    if args.perturbZ != 0:
        orig = telescope.itemDict[pm].surface
        coefs = np.random.normal(size=args.perturbZ+1)*1e-6 # micron perturbations
        perturbation = batoid.Zernike(coefs, R_outer=telescope.pupilSize)
        telescope.itemDict[pm].surface = batoid.Sum([orig, perturbation])

    # Optionally perturb primary mirror using bicubic spline
    if args.perturbBC != 0:
        orig = telescope.itemDict[pm].surface
        xs = np.linspace(-5, 5, 100)
        ys = np.linspace(-5, 5, 100)
        def f(x, y):
            return args.perturbBC*(np.cos(x) + np.sin(y))
        zs = f(*np.meshgrid(xs, ys))
        bc = batoid.Bicubic(xs, ys, zs)
        telescope.itemDict[pm].surface = batoid.Sum([orig, bc])

    print("Immutable trace")
    t0 = time.time()
    rays_out, _ = telescope.trace(rays)
    t1 = time.time()
    print("{} rays per second".format(int(nrays/(t1-t0))))
    print()

    print("Trace in place")
    t0 = time.time()
    telescope.traceInPlace(rays)
    t1 = time.time()
    print("{} rays per second".format(int(nrays/(t1-t0))))

    assert rays == rays_out

    if args.plot:
        import matplotlib.pyplot as plt
        rays.trimVignettedInPlace()
        x = rays.x
        y = rays.y
        x -= np.mean(x)
        y -= np.mean(y)
        x *= 1e6
        y *= 1e6
        plt.scatter(x, y, s=1, alpha=0.01)
        plt.xlim(np.std(x)*np.r_[-3,3])
        plt.ylim(np.std(y)*np.r_[-3,3])
        plt.xlabel("x (microns)")
        plt.ylabel("y (microns)")
        plt.show()
示例#8
0
def parallel_trace_timing(nside=1024, nthread=None, minChunk=None):
    if nthread is not None:
        print("setting nthread to {}".format(nthread))
        batoid._batoid.setNThread(nthread)
    print("Using {} threads".format(batoid._batoid.getNThread()))

    if minChunk is not None:
        print("setting minChunk to {}".format(minChunk))
        batoid._batoid.setMinChunk(minChunk)
    print("Using minChunk of {}".format(batoid._batoid.getMinChunk()))

    # 0.3, 0.3 should be in bounds for current wide-field telescopes
    dirCos = batoid.utils.gnomicToDirCos(np.deg2rad(0.3), np.deg2rad(0.3))

    if args.lsst:
        fn = os.path.join(batoid.datadir, "LSST", "LSST_i.yaml")
        pm = 'LSST.M1'
    elif args.decam:
        fn = os.path.join(batoid.datadir, "DECam", "DECam.yaml")
        pm = 'BlancoDECam.PM'
    else:
        fn = os.path.join(batoid.datadir, "HSC", "HSC.yaml")
        pm = 'SubaruHSC.PM'
    config = yaml.load(open(fn))
    telescope = batoid.parse.parse_optic(config['opticalSystem'])

    rays = batoid.circularGrid(
        telescope.dist, 0.5 * telescope.pupilSize,
        0.5 * telescope.pupilObscuration * telescope.pupilSize, dirCos[0],
        dirCos[1], -dirCos[2], nside, nside, 750e-9, 1.0, telescope.inMedium)

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

    # Optionally perturb the primary mirror using Zernike polynomial
    if args.perturbZ != 0:
        orig = telescope.itemDict[pm].surface
        coefs = np.random.normal(size=args.perturbZ +
                                 1) * 1e-6  # micron perturbations
        perturbation = batoid.Zernike(coefs, R_outer=telescope.pupilSize)
        telescope.itemDict[pm].surface = batoid.Sum([orig, perturbation])

    # Optionally perturb primary mirror using bicubic spline
    if args.perturbBC != 0:
        orig = telescope.itemDict[pm].surface
        rad = telescope.pupilSize / 2 * 1.1
        xs = np.linspace(-rad, rad, 100)
        ys = np.linspace(-rad, rad, 100)

        def f(x, y):
            return args.perturbBC * (np.cos(x) + np.sin(y))

        zs = f(*np.meshgrid(xs, ys))
        bc = batoid.Bicubic(xs, ys, zs)
        telescope.itemDict[pm].surface = batoid.Sum([orig, bc])

    if args.immutable:
        print("Immutable trace")
        t0 = time.time()

        for _ in range(args.nrepeat):
            rays_in = batoid.RayVector(rays)
            rays_out, _ = telescope.trace(rays_in)

        t1 = time.time()
        print("{} rays per second".format(int(nrays * args.nrepeat /
                                              (t1 - t0))))
        print()
    else:
        print("Trace in place")
        t0 = time.time()

        for _ in range(args.nrepeat):
            rays_out = batoid.RayVector(rays)
            telescope.traceInPlace(rays_out)

        t1 = time.time()
        print("{} rays per second".format(int(nrays * args.nrepeat /
                                              (t1 - t0))))

    if args.plot:
        import matplotlib.pyplot as plt
        rays_out.trimVignettedInPlace()
        x = rays_out.x
        y = rays_out.y
        x -= np.mean(x)
        y -= np.mean(y)
        x *= 1e6
        y *= 1e6
        plt.scatter(x, y, s=1, alpha=0.01)
        plt.xlim(np.std(x) * np.r_[-5, 5])
        plt.ylim(np.std(y) * np.r_[-5, 5])
        plt.xlabel("x (microns)")
        plt.ylabel("y (microns)")
        plt.show()