Example #1
0
    def __init__(self):
        # CLEARP pupil info from:
        #   MODIFIED CALIBRATION OPTIC HOLDER - NIRISS
        #   DRAWING NO 196847  REV 0  COMDEV
        #   Design file name 196847Rev0.pdf sent by Loic Albert
        # Properties:
        #  39 mm outer diam, corresponds to the circumscribing pupil of JWST
        #  2.0 mm vane width
        #  6.0 mm radius for central obstruction
        # Note the circumscribing pupil of JWST is 6603.464 mm in diameter
        #  (Ball SER on geometric optics model: BALL-JWST-SYST-05-003)

        pupil_mag = 6.603464 / 39.0
        poppy.CompoundAnalyticOptic.__init__(
            self,
            (
                poppy.SecondaryObscuration(
                    secondary_radius=6.0 * pupil_mag,
                    support_width=2.0 * pupil_mag,
                    n_supports=3,
                    support_angle_offset=90 +
                    180),  # align first support with +V2 axis
                # but invert to match OTE exit pupil
                poppy.CircularAperture(radius=39 * pupil_mag / 2)),
            name='CLEARP')
Example #2
0
def test_inwave_fresnel(plot=False):
    '''Verify basic functionality of the inwave kwarg for a basic FresnelOpticalSystem()'''
    npix = 128
    oversample = 2
    # HST example - Following example in PROPER Manual V2.0 page 49.
    lambda_m = 0.5e-6 * u.m
    diam = 2.4 * u.m
    fl_pri = 5.52085 * u.m
    d_pri_sec = 4.907028205 * u.m
    fl_sec = -0.6790325 * u.m
    d_sec_to_focus = 6.3919974 * u.m

    m1 = poppy.QuadraticLens(fl_pri, name='Primary')
    m2 = poppy.QuadraticLens(fl_sec, name='Secondary')

    hst = poppy.FresnelOpticalSystem(pupil_diameter=diam,
                                     npix=npix,
                                     beam_ratio=1 / oversample)
    hst.add_optic(poppy.CircularAperture(radius=diam.value / 2))
    hst.add_optic(
        poppy.SecondaryObscuration(secondary_radius=0.396,
                                   support_width=0.0264,
                                   support_angle_offset=45.0))
    hst.add_optic(m1)
    hst.add_optic(m2, distance=d_pri_sec)
    hst.add_optic(poppy.ScalarTransmission(
        planetype=poppy_core.PlaneType.image, name='focus'),
                  distance=d_sec_to_focus)

    if plot:
        plt.figure(figsize=(12, 8))
    psf1, wfs1 = hst.calc_psf(wavelength=lambda_m,
                              display_intermediates=plot,
                              return_intermediates=True)

    # now test the system by inputting a wavefront first
    wfin = poppy.FresnelWavefront(beam_radius=diam / 2,
                                  wavelength=lambda_m,
                                  npix=npix,
                                  oversample=oversample)
    if plot:
        plt.figure(figsize=(12, 8))
    psf2, wfs2 = hst.calc_psf(wavelength=lambda_m,
                              display_intermediates=plot,
                              return_intermediates=True,
                              inwave=wfin)

    wf = wfs1[-1].wavefront
    wf_no_in = wfs2[-1].wavefront

    assert np.allclose(
        wf, wf_no_in
    ), 'Results differ unexpectedly when using inwave argument for FresnelOpticalSystem().'
Example #3
0
def make_hawki_poppy_psf():
    import poppy

    osys = poppy.OpticalSystem()
    m1 = poppy.CircularAperture(radius=4.1)
    spiders = poppy.SecondaryObscuration(secondary_radius=0.6,
                                         n_supports=4,
                                         support_width=0.1)
    vlt = poppy.CompoundAnalyticOptic(opticslist=[m1, spiders], name='VLT')

    psfs = []
    seeing = 0.4
    see_psf = simcado.psf.seeing_psf(fwhm=seeing, size=384, pix_res=0.106 / 2)

    for lam in [1.2, 1.6, 2.2]:
        osys = poppy.OpticalSystem()
        osys.add_pupil(vlt)
        osys.add_detector(pixelscale=0.106, fov_arcsec=0.106 * 192)
        diff_psf = osys.calc_psf(lam * 1e-6)

        tmp = deepcopy(diff_psf)
        tmp[0].data = fftconvolve(diff_psf[0].data,
                                  see_psf[0].data,
                                  mode="same")
        tmp[0].data /= np.sum(tmp[0].data)

        tmp[0].header["SEEING"] = seeing
        tmp[0].header["CDELT1"] = tmp[0].header["PIXELSCL"]
        tmp[0].header["CDELT2"] = tmp[0].header["PIXELSCL"]

        psfs += tmp

    hdus = fits.HDUList(psfs)
    for i in range(1, len(hdus)):
        hdus[i] = fits.ImageHDU(data=hdus[i].data, header=hdus[i].header)

    hdus.writeto("HAWK-I_config/PSF_HAWKI_poppy.fits", clobber=True)

    fname = "HAWK-I_config/PSF_HAWKI_poppy.fits"

    plt.figure(figsize=(15, 4))
    for i in range(3):
        plt.subplot(1, 3, i + 1)
        poppy.display_PSF(fname,
                          ext=i,
                          title="HAWKI PSF lambda=" +
                          str(fits.getheader(fname, ext=i)["WAVELEN"]))

    plt.show()
Example #4
0
def test_inwave_fraunhofer(plot=False):
    '''Verify basic functionality of the inwave kwarg for a basic OpticalSystem()'''
    npix = 128
    oversample = 2
    diam = 2.4 * u.m
    lambda_m = 0.5e-6 * u.m
    # calculate the Fraunhofer diffraction pattern
    hst = poppy.OpticalSystem(pupil_diameter=diam,
                              npix=npix,
                              oversample=oversample)
    hst.add_pupil(poppy.CircularAperture(radius=diam.value / 2))
    hst.add_pupil(
        poppy.SecondaryObscuration(secondary_radius=0.396,
                                   support_width=0.0264,
                                   support_angle_offset=45.0))
    hst.add_image(
        poppy.ScalarTransmission(planetype=poppy_core.PlaneType.image,
                                 name='focus'))

    if plot:
        plt.figure(figsize=(9, 3))
    psf1, wfs1 = hst.calc_psf(wavelength=lambda_m,
                              display_intermediates=plot,
                              return_intermediates=True)

    # now test the system by inputting a wavefront first
    wfin = poppy.Wavefront(wavelength=lambda_m,
                           npix=npix,
                           diam=diam,
                           oversample=oversample)
    if plot:
        plt.figure(figsize=(9, 3))
    psf2, wfs2 = hst.calc_psf(wavelength=lambda_m,
                              display_intermediates=plot,
                              return_intermediates=True,
                              inwave=wfin)

    wf = wfs1[-1].wavefront
    wf_no_in = wfs2[-1].wavefront

    assert np.allclose(
        wf, wf_no_in
    ), 'Results differ unexpectedly when using inwave argument in OpticalSystem().'
Example #5
0
 def multi_hexagon(rings_number, sec_rad, side_dist = 1.0, segment_gap = 0.01):
         """ 
 multi_hexagon(rings_number, sec_rad, side_dist = 1.0, segment_gap = 0.01)
 # rings : The number of rings of hexagons to include, not counting the central segment
 
 # side_dist : Distance between sides (flat-to-flat) of the hexagon, in meters. Default is 1.0
 
 # segment_gap : Gap between adjacent segments, in meters. Default is 0.01 m = 1 cm
 
 # sec_rad : scondary obstacle radius
     
         """
     
         ap = poppy.MultiHexagonAperture(name='ApertureHex', flattoflat = side_dist, gap = segment_gap,rings =rings_number)  # 3 rings of 2 m segments yields 14.1 m circumscribed diameter
         sec = poppy.SecondaryObscuration(secondary_radius = float(sec_rad), n_supports = 4, support_width = 0.1)   # secondary with spiders
         atlast = poppy.CompoundAnalyticOptic( opticslist=[ap, sec], name='Mock ATLAST')           # combine into one optic
     
         plt.figure(figsize=(12,8))
         atlast.display(npix=1024, colorbar_orientation='vertical')
         return atlast
Example #6
0
File: comp.py Project: mbu54/mini3
import matplotlib.pyplot as plt
import logging
logging.basicConfig(level=logging.DEBUG)

np.seterr(divide='ignore', invalid='ignore')
osys = poppy.OpticalSystem()
osys.add_pupil(poppy.CircularAperture(radius=3))  # pupil radius in meters
osys.add_detector(pixelscale=0.010, fov_arcsec=5.0)

plt.figure(figsize=(16, 12))

ap = poppy.MultiHexagonAperture(
    rings=3, flattoflat=2
)  # 3 rings of 2 m segments yields 14.1 m circumscribed diameter
sec = poppy.SecondaryObscuration(secondary_radius=1.5,
                                 n_supports=4,
                                 support_width=0.1)  # secondary with spiders
atlast = poppy.CompoundAnalyticOptic(
    opticslist=[ap, sec], name='Mock ATLAST')  # combine into one optic

atlast.display(npix=1024, colorbar_orientation='vertical')
plt.savefig('example_atlast_pupil.png', dpi=100)

plt.figure(figsize=(8, 6))

osys = poppy.OpticalSystem()
osys.add_pupil(atlast)
osys.add_detector(pixelscale=0.010, fov_arcsec=2.0)
psf = osys.calc_psf(1e-6)

poppy.display_psf(psf, title="Mock ATLAST PSF")
Example #7
0
def test_fresnel_noninteger_oversampling(display_intermediates=False):
    '''Test for noninteger oversampling for basic FresnelOpticalSystem() using HST example system'''
    lambda_m = 0.5e-6 * u.m
    # lambda_m = np.linspace(0.475e-6, 0.525e-6, 3) * u.m
    diam = 2.4 * u.m
    fl_pri = 5.52085 * u.m
    d_pri_sec = 4.907028205 * u.m
    fl_sec = -0.6790325 * u.m
    d_sec_to_focus = 6.3919974 * u.m

    m1 = poppy.QuadraticLens(fl_pri, name='Primary')
    m2 = poppy.QuadraticLens(fl_sec, name='Secondary')
    image_plane = poppy.ScalarTransmission(
        planetype=poppy_core.PlaneType.image, name='focus')

    npix = 128

    oversample1 = 2
    hst1 = poppy.FresnelOpticalSystem(pupil_diameter=diam,
                                      npix=npix,
                                      beam_ratio=1 / oversample1)
    hst1.add_optic(poppy.CircularAperture(radius=diam.value / 2))
    hst1.add_optic(
        poppy.SecondaryObscuration(secondary_radius=0.396,
                                   support_width=0.0264,
                                   support_angle_offset=45.0))
    hst1.add_optic(m1)
    hst1.add_optic(m2, distance=d_pri_sec)
    hst1.add_optic(image_plane, distance=d_sec_to_focus)

    if display_intermediates: plt.figure(figsize=(12, 8))
    psf1 = hst1.calc_psf(wavelength=lambda_m,
                         display_intermediates=display_intermediates)

    # now test the second system which has a different oversampling factor
    oversample2 = 2.0
    hst2 = poppy.FresnelOpticalSystem(pupil_diameter=diam,
                                      npix=npix,
                                      beam_ratio=1 / oversample2)
    hst2.add_optic(poppy.CircularAperture(radius=diam.value / 2))
    hst2.add_optic(
        poppy.SecondaryObscuration(secondary_radius=0.396,
                                   support_width=0.0264,
                                   support_angle_offset=45.0))
    hst2.add_optic(m1)
    hst2.add_optic(m2, distance=d_pri_sec)
    hst2.add_optic(image_plane, distance=d_sec_to_focus)

    if display_intermediates: plt.figure(figsize=(12, 8))
    psf2 = hst2.calc_psf(wavelength=lambda_m,
                         display_intermediates=display_intermediates)

    # Now test a 3rd HST system with oversample of 2.5 and compare to hardcoded result
    oversample3 = 2.5
    hst3 = poppy.FresnelOpticalSystem(pupil_diameter=diam,
                                      npix=npix,
                                      beam_ratio=1 / oversample3)
    hst3.add_optic(poppy.CircularAperture(radius=diam.value / 2))
    hst3.add_optic(
        poppy.SecondaryObscuration(secondary_radius=0.396,
                                   support_width=0.0264,
                                   support_angle_offset=45.0))
    hst3.add_optic(m1)
    hst3.add_optic(m2, distance=d_pri_sec)
    hst3.add_optic(image_plane, distance=d_sec_to_focus)

    if display_intermediates: plt.figure(figsize=(12, 8))
    psf3 = hst3.calc_psf(wavelength=lambda_m,
                         display_intermediates=display_intermediates)

    assert np.allclose(
        psf1[0].data, psf2[0].data
    ), 'PSFs with oversampling 2 and 2.0 are surprisingly different.'
    np.testing.assert_almost_equal(
        psf3[0].header['PIXELSCL'],
        0.017188733797782272,
        decimal=7,
        err_msg=
        'pixelscale for the PSF with oversample of 2.5 is surprisingly different from expected result.'
    )
Example #8
0
    0.8,
    0.065,  # 7.5 cm semimajor
    0.5  # phase
)
m1.name = 'TOLIMAN rosette primary mirror'

toliman = poppy.FresnelOpticalSystem(name='TOLIMAN telescope',
                                     pupil_diameter=m1_rad,
                                     npix=1024,
                                     beam_ratio=0.5)

# Secondary mirror obscuration & spider
toliman.add_optic(
    poppy.SecondaryObscuration(name='Secondary mirror support',
                               secondary_radius=m2_rad,
                               n_supports=m2_supports,
                               support_width=m2_strut_width,
                               support_angle_offset=0 * u.deg), pupil_m2_dist)

# Primary mirror
# Rosette components
toliman.add_optic(m1, m1_m2_dist)
# Central aperture - treat as a secondary obscuration with no spider
toliman.add_optic(
    poppy.SecondaryObscuration(name='Secondary mirror support',
                               secondary_radius=m1_aperture_rad,
                               n_supports=0),
    0 * u.m)  # actually should be a bit further along
# Mirror component
toliman.add_optic(
    poppy.fresnel.ConicLens(f_lens=m1_fl,
Example #9
0
def make_coronagraph(wfe_coeffs,npix_pupil=512,npix_detector=128,wavelength=1e-6*u.m,oversample=4,pixelscale=0.01,sensor_defocus=0.5,vortex_charge=2,llowfs=False,mask_type='fqpm',obscuration=False,lyot_factor=0.9):
    #sensor_defocus: defocus of llowfs detector in waves peak-to-valley
    
    #these values are picked rather arbitrarily, but seem to work
    aperture_radius = 3*u.m
    #lyot_radius=2.6*u.m
    lyot_radius=lyot_factor*aperture_radius
    pupil_radius = 3*aperture_radius

    
    #create the optical system
    osys = poppy.OpticalSystem("LLOWFS", oversample=oversample, npix=npix_pupil, pupil_diameter=2*pupil_radius)
    
    ap = poppy.CircularAperture(radius=aperture_radius)
    if obscuration:
        obsc = poppy.SecondaryObscuration(secondary_radius=0.5*u.m, n_supports=0)
        osys.add_pupil(poppy.CompoundAnalyticOptic(opticslist=[ap,obsc])) #osys.add_pupil(poppy.AsymmetricSecondaryObscuration(secondary_radius=0.5,support_width=0.2*u.meter,support_angle=(0,120,240)))
    else:
        osys.add_pupil(ap)
        
    error = poppy.ZernikeWFE(radius=aperture_radius, coefficients=wfe_coeffs)
    osys.add_pupil(error)
    
    #inject wavefrotn error at the pupil
    
    
    #correct for fqpm (and vvc) alignment
    osys.add_pupil(poppy.FQPM_FFT_aligner())
    osys.add_image() #helper for plotting intermediates
    
    #select mask type
    if mask_type is 'fqpm':
        cgph_mask = poppy.IdealFQPM(wavelength=wavelength,name='FQPM Mask')
    elif mask_type is 'vortex':
        cgph_mask = VortexMask(charge=vortex_charge,wavelength=wavelength,name='Vortex Mask')
    else:
        raise ValueError("mask_type must be 'fqpm' or 'vortex'")
    cgph_mask._wavefront_display_hint='phase'
    osys.add_image(cgph_mask)
    
    #correct alignment back the other way
    osys.add_pupil(poppy.FQPM_FFT_aligner(direction='backward'))
    #osys.add_pupil()
    
    lyot = poppy.CircularAperture(radius=lyot_radius,name='Lyot Stop')
    lyot._wavefront_display_hint='intensity'
    if obscuration:
        lyot_obsc = poppy.InverseTransmission(poppy.SquareAperture(size=1.4*u.m))
        lyot = poppy.CompoundAnalyticOptic(opticslist=[lyot,lyot_obsc])

    if llowfs:
        #take the rejected light for the LLOWFS
        lyot_reflection = poppy.InverseTransmission(lyot)
        lyot_extent = poppy.CircularAperture(radius=pupil_radius)
        lyot = poppy.CompoundAnalyticOptic(opticslist = [lyot_reflection,lyot_extent])
        lyot._wavefront_display_hint='intensity'
        osys.add_pupil(lyot)
        #if obscuration:
        #    obsc = poppy.InverseTransmission(obsc)
        #    osys.add_pupil(obsc)

        
        #Add a defocus term to the sensor
        #Calc of peak-to-valley WFE: https://poppy-optics.readthedocs.io/en/stable/wfe.html
        defocus_coeff = sensor_defocus*wavelength.to(u.m).value
        sensor_defocus_wfe = poppy.ZernikeWFE(radius=pupil_radius,coefficients=[0,0,0,defocus_coeff])
        osys.add_pupil(sensor_defocus_wfe)
        

        #osys.add_pupil()
        osys.add_detector(pixelscale=pixelscale, fov_pixels=npix_detector, oversample=1)
    else:
        #add lyot stop
        osys.add_pupil(lyot)
        osys.add_detector(pixelscale=pixelscale, fov_arcsec=1)
        
    return osys