Ejemplo n.º 1
0
def test_prescreen():
    """Add an OPDScreen in front of LSST entrance pupil.  The OPD that comes out
    should be _negative_ the added phase delay by convention.
    """
    lsst = batoid.Optic.fromYaml("LSST_r.yaml")
    wavelength = 620e-9

    z_ref = batoid.zernikeGQ(
        lsst, 0, 0, wavelength, rings=10, reference='chief', jmax=37, eps=0.61
    )
    rng = np.random.default_rng(577)

    for i in range(4, 38):
        amplitude = rng.uniform(0.1, 0.2)
        zern = batoid.Zernike(
            np.array([0]*i+[amplitude])*wavelength,
            R_outer=4.18, R_inner=0.61*4.18
        )

        tel = batoid.CompoundOptic(
            (
                batoid.optic.OPDScreen(
                    batoid.Plane(),
                    zern,
                    name='PS',
                    obscuration=batoid.ObscNegation(batoid.ObscCircle(5.0)),
                    coordSys=lsst.stopSurface.coordSys
                ),
                *lsst.items
            ),
            name='PS0',
            backDist=lsst.backDist,
            pupilSize=lsst.pupilSize,
            inMedium=lsst.inMedium,
            stopSurface=lsst.stopSurface,
            sphereRadius=lsst.sphereRadius,
            pupilObscuration=lsst.pupilObscuration
        )
        do_pickle(tel)

        zGQ = batoid.zernikeGQ(
            tel, 0, 0, wavelength, rings=10, reference='chief', jmax=37, eps=0.61
        )
        zTA = batoid.zernikeTA(
            tel, 0, 0, wavelength, nrad=10, naz=60, reference='chief', jmax=37, eps=0.61
        )

        z_expect = np.zeros_like(zGQ)
        z_expect[i] = -amplitude  # Longer OPL => negative OPD
        np.testing.assert_allclose(
            (zGQ-z_ref)[4:], z_expect[4:],
            rtol=0, atol=5e-4
        )
        # Distortion makes this comparison less precise
        np.testing.assert_allclose(
            zGQ[4:], zTA[4:],
            rtol=0, atol=5e-3
        )
Ejemplo n.º 2
0
def test_doubleZernike():
    telescope = batoid.Optic.fromYaml("LSST_r.yaml")
    dz = batoid.doubleZernike(telescope,
                              np.deg2rad(1.75),
                              625e-9,
                              10,
                              kmax=28,
                              jmax=22)

    # Now evaluate DZ a few places and compare with zernikeGQ
    size = 20
    js = np.random.randint(4, 22, size=size)
    thr = np.deg2rad(np.sqrt(np.random.uniform(0, 1.75**2, size=size)))
    thth = np.random.uniform(0, 2 * np.pi, size=size)
    thx = thr * np.cos(thth)
    thy = thr * np.sin(thth)

    for j in js:
        Z = galsim.zernike.Zernike(dz[:, j],
                                   R_inner=0.0,
                                   R_outer=np.deg2rad(1.75))
        for thx_, thy_ in zip(thx, thy):
            zGQ = batoid.zernikeGQ(telescope, thx_, thy_, 625e-9, jmax=22)
            np.testing.assert_allclose(Z(thx_, thy_),
                                       zGQ[j],
                                       rtol=0,
                                       atol=1e-4)

    # Check that we get similar results with different number of rings/spokes
    dz2 = batoid.doubleZernike(telescope,
                               np.deg2rad(1.75),
                               625e-9,
                               rings=12,
                               spokes=29,
                               kmax=28,
                               jmax=22)
    np.testing.assert_allclose(dz, dz2, rtol=0, atol=1e-2)
Ejemplo n.º 3
0
def test_rotation():
    rng = np.random.default_rng(57)

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

    rot = batoid.RotX(rng.uniform(low=0.0, high=2 * np.pi))
    rot = rot.dot(batoid.RotY(rng.uniform(low=0.0, high=2 * np.pi)))
    rot = rot.dot(batoid.RotZ(rng.uniform(low=0.0, high=2 * np.pi)))
    rotInv = np.linalg.inv(rot)

    # It's hard to test the two telescopes for equality due to rounding errors,
    # so we test by comparing zernikes
    rotTel = telescope.withLocalRotation(rot).withLocalRotation(rotInv)

    theta_x = rng.uniform(-0.005, 0.005)
    theta_y = rng.uniform(-0.005, 0.005)
    wavelength = 750e-9

    for k in telescope.itemDict.keys():
        np.testing.assert_allclose(telescope[k].coordSys.origin,
                                   rotTel[k].coordSys.origin,
                                   rtol=0,
                                   atol=1e-14)
        np.testing.assert_allclose(telescope[k].coordSys.rot,
                                   rotTel[k].coordSys.rot,
                                   rtol=0,
                                   atol=1e-14)

    np.testing.assert_allclose(batoid.zernikeGQ(telescope, theta_x, theta_y,
                                                wavelength),
                               batoid.zernikeGQ(rotTel, theta_x, theta_y,
                                                wavelength),
                               atol=1e-7)

    for item in telescope.itemDict:
        rotTel = telescope.withLocallyRotatedOptic(item, rot)
        rotTel = rotTel.withLocallyRotatedOptic(item, rotInv)
        rotTel2 = telescope.withLocallyRotatedOptic(item, np.eye(3))
        theta_x = rng.uniform(-0.005, 0.005)
        theta_y = rng.uniform(-0.005, 0.005)
        np.testing.assert_allclose(batoid.zernikeGQ(telescope, theta_x,
                                                    theta_y, wavelength),
                                   batoid.zernikeGQ(rotTel, theta_x, theta_y,
                                                    wavelength),
                                   atol=1e-7)
        np.testing.assert_allclose(batoid.zernikeGQ(telescope, theta_x,
                                                    theta_y, wavelength),
                                   batoid.zernikeGQ(rotTel2, theta_x, theta_y,
                                                    wavelength),
                                   atol=1e-7)
    # Test with non-fully-qualified name
    rotTel = telescope.withLocallyRotatedOptic('G1', rot)
    rotTel = rotTel.withLocallyRotatedOptic('G1', rotInv)
    rotTel2 = rotTel.withLocallyRotatedOptic('G1', np.eye(3))
    np.testing.assert_allclose(batoid.zernikeGQ(telescope, theta_x, theta_y,
                                                wavelength),
                               batoid.zernikeGQ(rotTel, theta_x, theta_y,
                                                wavelength),
                               atol=1e-7)
    np.testing.assert_allclose(batoid.zernikeGQ(telescope, theta_x, theta_y,
                                                wavelength),
                               batoid.zernikeGQ(rotTel2, theta_x, theta_y,
                                                wavelength),
                               atol=1e-7)
Ejemplo n.º 4
0
def test_zernikeGQ():
    if __name__ == '__main__':
        nx = 1024
        rings = 10
        tol = 1e-4
    else:
        nx = 128
        rings = 5
        tol = 1e-3
    telescope = batoid.Optic.fromYaml("LSST_r.yaml")
    telescope.clearObscuration()
    telescope['LSST.M1'].obscuration = batoid.ObscNegation(
        batoid.ObscCircle(4.18))
    zSquare = batoid.zernike(telescope,
                             0.0,
                             0.0,
                             625e-9,
                             nx=nx,
                             jmax=28,
                             reference='chief')
    zGQ = batoid.zernikeGQ(telescope,
                           0.0,
                           0.0,
                           625e-9,
                           rings=rings,
                           jmax=28,
                           reference='chief')

    np.testing.assert_allclose(zSquare, zGQ, rtol=0, atol=tol)

    # Repeat with annular Zernikes
    telescope['LSST.M1'].obscuration = batoid.ObscNegation(
        batoid.ObscAnnulus(0.61 * 4.18, 4.18))
    zSquare = batoid.zernike(telescope,
                             0.0,
                             0.0,
                             625e-9,
                             nx=nx,
                             jmax=28,
                             reference='chief',
                             eps=0.61)
    zGQ = batoid.zernikeGQ(telescope,
                           0.0,
                           0.0,
                           625e-9,
                           rings=rings,
                           jmax=28,
                           reference='chief',
                           eps=0.61)

    np.testing.assert_allclose(zSquare, zGQ, rtol=0, atol=tol)

    # Try off-axis
    zSquare = batoid.zernike(telescope,
                             np.deg2rad(0.2),
                             np.deg2rad(0.1),
                             625e-9,
                             nx=nx,
                             jmax=28,
                             reference='chief',
                             eps=0.61)
    zGQ = batoid.zernikeGQ(telescope,
                           np.deg2rad(0.2),
                           np.deg2rad(0.1),
                           625e-9,
                           rings=rings,
                           jmax=28,
                           reference='chief',
                           eps=0.61)

    np.testing.assert_allclose(zSquare, zGQ, rtol=0, atol=tol)

    # Try reference == mean
    # Try off-axis
    zSquare = batoid.zernike(telescope,
                             np.deg2rad(0.2),
                             np.deg2rad(0.1),
                             625e-9,
                             nx=nx,
                             jmax=28,
                             reference='mean',
                             eps=0.61)
    zGQ = batoid.zernikeGQ(telescope,
                           np.deg2rad(0.2),
                           np.deg2rad(0.1),
                           625e-9,
                           rings=rings,
                           jmax=28,
                           reference='mean',
                           eps=0.61)
    # Z1-3 less reliable, but mostly uninteresting anyway...
    np.testing.assert_allclose(zSquare[4:], zGQ[4:], rtol=0, atol=tol)