Beispiel #1
0
    def do_test_3_fqpm_tilt(self):
        """ Test FQPM tilting (no FQPM yet), no field mask. Verify proper behavior in Lyot plane"""

        osys = poppy.OpticalSystem("test", oversample=self.oversample)
        osys.addPupil('Circle', radius=6.5/2)
        osys.addPupil('FQPM_FFT_aligner')
        osys.addImage()  # perfect image plane
        osys.addPupil('FQPM_FFT_aligner', direction='backward')
        osys.addPupil('Circle', radius=6.5/2)
        osys.addDetector(pixelscale=self.pixelscale, fov_arcsec=3.0)
            #TODO testing of odd and even focal plane sizes?
        
        plt.clf()
        poppy._FLUXCHECK=True
        psf = osys.calcPSF(wavelength=self.wavelength, save_intermediates=True, display_intermediates=True)
        psf.writeto('test3a_psf.fits', clobber=True)

        # after the Lyot plane, the wavefront should be all real. 
        check_wavefront('wavefront_plane_004.fits', test='is_real', comment='(Lyot Plane)')

        cen = webbpsf.measure_centroid('wavefront_plane_002.fits', boxsize=50)
        head = pyfits.getheader('wavefront_plane_002.fits')
        desired_pos = (head['NAXIS1']-1)/2.0
        self.assertAlmostEqual( cen[0], desired_pos, delta=0.025) #within 1/50th of a pixel of desired pos?
        self.assertAlmostEqual( cen[1], desired_pos, delta=0.025) #within 1/50th of a pixel of desired pos?
                # This is likely dominated by uncertainties in the simple center measuring algorithm...

        _log.info("FQPM FFT half-pixel tilting is working properly in intermediate image plane")

        cen2 = webbpsf.measure_centroid('wavefront_plane_005.fits', boxsize=50)
        head2 = pyfits.getheader('wavefront_plane_005.fits')
        desired_pos2 = (head2['NAXIS1']-1)/2.0
        self.assertAlmostEqual( cen2[0], desired_pos2, delta=0.05) #within 1/20th of a pixel of desired pos?
                                    
        _log.info("FQPM FFT half-pixel tilting is working properly in final image plane")
Beispiel #2
0
def test_single_seg_psf(segmentid=1):
    """Test calculation of a single segment PSF, including options to remove piston/tip/tilt as used by MIRAGE

    """

    nrc = webbpsf.NIRCam()
    nrc.filter = 'F212N'
    nrc, ote = webbpsf.enable_adjustable_ote(nrc)
    ote.zero(zero_original=True)

    segname = webbpsf.constants.SEGNAMES_WSS_ORDER[segmentid-1][0:2]

    ote.move_seg_local(segname, xtilt=1, piston=-1)

    pupil = webbpsf.webbpsf_core.one_segment_pupil(segmentid)
    ote.amplitude = pupil[0].data


    psf = nrc.calc_psf(nlambda=1)

    ote.remove_piston = True
    ote.update_opd()
    psf_rm_piston = nrc.calc_psf(nlambda=1)
    assert np.allclose(psf[0].data, psf_rm_piston[0].data), "Piston removal should not affect the overall PSF"

    assert np.allclose( webbpsf.measure_centroid(psf), webbpsf.measure_centroid(psf_rm_piston)), "centroid should not shift"

    ote.remove_piston_tip_tilt = True
    ote.update_opd()
    psf_rm_ptt = nrc.calc_psf(nlambda=1)
    assert not np.allclose(psf[0].data, psf_rm_ptt[0].data), "Piston/Tip/Tip removal should shift the overall PSF"
    assert np.abs(webbpsf.measure_centroid(psf)[0] - webbpsf.measure_centroid(psf_rm_ptt)[0]) > 40, "centroid should shift susbtantially with/without tip/tilt removal"
Beispiel #3
0
def test_pupilopd_none():
    """Test that setting pupilopd=None does in fact result in no WFE
    In particular, this tests that setting opd to None also results in
    disabling the field-dependent component of the OTE linear model,
    as well as setting the global WFE component to zero.
    """

    nrc = webbpsf.NIRCam()
    nrc.pupilopd = None
    nrc.include_si_wfe = False

    ote_lom = nrc.get_optical_system().planes[0]
    assert ote_lom.rms()==0, "RMS WFE should be strictly 0"

    psf_small = nrc.calc_psf(fov_pixels=50, monochromatic=2e-6, add_distortion=False)
    centroid = webbpsf.measure_centroid(psf_small, relativeto='center')
    assert np.abs(centroid[0]) < 1e-5, "Centroid should be (0,0)"
    assert np.abs(centroid[1]) < 1e-5, "Centroid should be (0,0)"
Beispiel #4
0
def test_segment_tilt_signs(fov_pix=50, plot=False):
    """Test that segments move in the direction expected when tilted.

    The local coordinate systems are non-obvious, to say the least. This verifies
    sign conventions and coordinates are consistent in the linear optical model and
    optical propagation code.

    """

    if plot:
        fig, axs = plt.subplots(3, 5,
                                figsize=(14,
                                         9))  #, sharex = True, sharey = True)

    nrc = webbpsf.NIRCam()

    ote = webbpsf.opds.OTE_Linear_Model_WSS()
    nrc.include_si_wfe = False  # not relevant for this test

    tilt = 1.0

    # We im for relatively minimalist PSF calcs, to reduce test runtime
    psf_kwargs = {
        'monochromatic': 2e-6,
        'fov_pixels': fov_pix,
        'oversample': 1,
        'add_distortion': False
    }

    # Which way are things expected to move?
    #
    # A1:  +X rotation -> -Y pixels (DMS), +Y rotation -> -X pixels
    # B1: +X rotation -> +Y pixels, +Y rotation -> +X pixels
    # C1: +X rotation -> +X/+Y pixels, +Y rotation -> -Y/+X pixels
    # (for C1, A/B means A is the sqrt(3)/2 component, B is the 1/2 component)
    #
    # The above derived from Code V models by R. Telfer, subsequently cross checked by Perrin

    for i, iseg in enumerate(['A1', 'B1', 'C1']):
        ote.zero()

        pupil = webbpsf.webbpsf_core.one_segment_pupil(iseg)

        ote.amplitude = pupil[0].data
        nrc.pupil = ote

        # CENTERED PSF:
        psf = nrc.calc_psf(**psf_kwargs)
        cen_ref = webbpsf.measure_centroid(psf, boxsize=10, threshold=1)

        ote.move_seg_local(iseg, xtilt=tilt)
        # XTILT PSF:
        psfx = nrc.calc_psf(**psf_kwargs)
        cen_xtilt = webbpsf.measure_centroid(psfx, boxsize=10, threshold=1)

        if iseg.startswith("A"):
            assert cen_xtilt[0] < cen_ref[
                0], "Expected A1:  +X rotation -> -Y pixels (DMS coords)"
            assert np.isclose(
                cen_xtilt[1], cen_ref[1],
                atol=1), "Expected A1:  +X rotation -> no change in X"
        elif iseg.startswith("A"):
            assert cen_xtilt[0] > cen_ref[
                0], "Expected B1: +X rotation -> +Y pixels(DMS coords)"
            assert np.isclose(
                cen_xtilt[1], cen_ref[1],
                atol=1), "Expected B1:  +X rotation -> no change in Y"
        elif iseg.startswith("C"):
            assert cen_xtilt[0] > cen_ref[
                0], "Expected C1: +X rotation -> +X/+Y pixels"
            assert cen_xtilt[1] > cen_ref[
                1], "Expected C1: +X rotation -> +X/+Y pixels"

        if plot:
            axs[i, 0].imshow(psf[0].data,
                             norm=matplotlib.colors.LogNorm(vmax=1e-2,
                                                            vmin=1e-5),
                             origin="lower")
            axs[i, 0].set_title(iseg + ": centered")
            axs[i, 0].axhline(y=fov_pix / 2)
            axs[i, 0].axvline(x=fov_pix / 2)
            # PLOT RESULTING OPD:
            im = axs[i, 1].imshow(ote.opd,
                                  vmin=-4e-6,
                                  vmax=4e-6,
                                  origin="lower")
            axs[i, 1].set_title("OPD (yellow +)")
            axs[i, 2].imshow(psfx[0].data,
                             norm=matplotlib.colors.LogNorm(vmax=1e-2,
                                                            vmin=1e-5),
                             origin="lower")
            axs[i, 2].set_title(iseg + ": xtilt {} um".format(tilt))
            axs[i, 2].axhline(y=fov_pix / 2)
            axs[i, 2].axvline(x=fov_pix / 2)

        ote.zero()
        ote.move_seg_local(iseg, ytilt=tilt)
        # YTILT PSF:
        psfy = nrc.calc_psf(**psf_kwargs)
        cen_ytilt = webbpsf.measure_centroid(psfy, boxsize=10, threshold=1)

        if iseg.startswith("A"):
            assert cen_ytilt[1] < cen_ref[
                1], "Expected A1:  +Y rotation -> -X pixels (DMS coords)"
            assert np.isclose(
                cen_ytilt[0], cen_ref[0],
                atol=1), "Expected A1:  +Y rotation -> no change in Y"
        elif iseg.startswith("A"):
            assert cenyxtilt[0] > cen_ref[
                0], "Expected B1: +Y rotation -> +X pixels(DMS coords)"
            assert np.isclose(
                cen_xtilt[0], cen_ref[0],
                atol=1), "Expected B1:  +Y rotation -> no change in Y"
        elif iseg.startswith("C"):
            assert cen_ytilt[0] < cen_ref[
                0], "Expected C1: +Y rotation -> -Y/+X pixels"
            assert cen_ytilt[1] > cen_ref[
                1], "Expected C1: +Y rotation -> -Y/+X pixels"

        # PLOT RESULTING OPD:
        if plot:
            im = axs[i, 3].imshow(ote.opd,
                                  vmin=-4e-6,
                                  vmax=4e-6,
                                  origin="lower")
            axs[i, 3].set_title("OPD (yellow +)")
            axs[i, 4].imshow(psfy[0].data,
                             norm=matplotlib.colors.LogNorm(vmax=1e-2,
                                                            vmin=1e-5),
                             origin="lower")
            axs[i, 4].set_title(iseg + ": ytilt {} um".format(tilt))
            axs[i, 4].axhline(y=fov_pix / 2)
            axs[i, 4].axvline(x=fov_pix / 2)