Ejemplo n.º 1
0
def exer4(odir):
    """ Precise control of image positioning using phase slopes? """
    # instantiate an mft object:
    ft = matrixDFT.MatrixFourierTransform()
    npup = 100
    radius = 20.0
    fp_size_reselt = 100
    pupil = utils.makedisk(npup, radius=radius)
    tilts = ((0,0),
             (0*np.pi/npup, 0), 
             (1*np.pi/npup, 0),
             (2*np.pi/npup, 0),
             (3*np.pi/npup, 0),
             (4*np.pi/npup, 0),
             (95*np.pi/npup, 0),
             (npup*np.pi/npup, 0))
    phases = utils.phasearrays(npup, tilts)
    for nt, ph in enumerate(phases):
        pupilarray = pupil * np.exp(1j * ph)
        imagefield = ft.perform(pupilarray, fp_size_reselt, npup)
        image_intensity = (imagefield*imagefield.conj()).real
        psf = image_intensity / image_intensity.max()  # peak intensity unity
        fits.PrimaryHDU(psf).writeto( 
            odir+"/ex4_tiltPi_a_{0:.3f}_b_{1:.3f}.fits".format(tilts[nt][0],tilts[nt][1]), 
            overwrite=True)
Ejemplo n.º 2
0
def exer5(odir):
    """ Create ripples of phase aberration in the pupil
        to simulate the Ruffles Potato Chip Telescope (RPCT) """
    # instantiate an mft object:
    ft = matrixDFT.MatrixFourierTransform()
    npup = 100
    radius = 20.0
    fp_size_reselt = 100
    pupil = utils.makedisk(npup, radius=radius)
    number_of_waves_across = (2,3,4,5,6)

    peaks = (0.0, 0.1, 0.3, 1.0, 3.0) # radians, amplitude of phase ripple
    arrayshape = (npup, npup)
    diam_pupil = radius*2 # pixels
    center = (arrayshape[0]/2, arrayshape[1]/2)
    for nwaves in number_of_waves_across:
        for peak in peaks: 
            for offset in (0, ):
                for angle in (0, ):
                    spatialwavelen = diam_pupil / nwaves
                    offset = offset * np.pi/180.0
                    khat = np.array((np.sin(angle*np.pi/180.0), np.cos(angle*np.pi/180.0))) # unit vector
                    kwavedata = np.fromfunction(utils.kwave2d, arrayshape,
                            spatialwavelen=spatialwavelen,
                            center=center,
                            offset=offset,
                            khat=khat)
                    pupilarray = pupil * np.exp(1j * peak * kwavedata)
                    imagefield = ft.perform(pupilarray, fp_size_reselt, npup)
                    image_intensity = (imagefield*imagefield.conj()).real
                    psf = image_intensity / image_intensity.max()  # peak intensity unity
                    fits.PrimaryHDU(peak*kwavedata).writeto( 
                         odir+"/ex5_pupilarrayripple_{0:d}acrossD_peak_{1:.1f}.fits".format(nwaves,peak), 
                         overwrite=True)
Ejemplo n.º 3
0
def create_input_datafiles(rfn=None):
    """
        Pupil and image data, true (zero mean) phase map (rad) 
        No de-tilting of the thase done.
        Didactic case, no input parameters: create the pupil & monochromatic image 
        on appropriate pixel scales.  
        Pupil and image arrays of same size, ready to FT into each 
        other losslessly.  For real data you'll need to worry about adjusting
        sizes to satify this sampling relation between the two planes.
        For finite bandwidth data image simulation will loop over wavelengths.
        For coarsely sampled pixels image simulation will need to use finer
        sampling and rebin to detector pixel sizes.
        [email protected] Jan 2019
    """
    pupil0 = utils.makedisk(250, radius=50)  # D=100 pix, array 250 pix
    pupil1 = (pupil0 -
              utils.makedisk(250, radius=15, ctr=(125.0, 75.0))) * pupil0
    pupil2 = (pupil1 -
              utils.makedisk(250, radius=15, ctr=(90.0, 90.0))) * pupil0
    pupil3 = (pupil2 -
              utils.makedisk(250, radius=15, ctr=(75.0, 125.0))) * pupil0
    fits.writeto(rfn + "0__input_pup.fits", pupil0, overwrite=True)
    fits.writeto(rfn + "1__input_pup.fits", pupil1, overwrite=True)
    fits.writeto(rfn + "2__input_pup.fits", pupil2, overwrite=True)
    fits.writeto(rfn + "3__input_pup.fits", pupil3, overwrite=True)

    for pnum in (0, 1, 2, 3):
        pupil = fits.getdata(rfn + "{:1d}__input_pup.fits".format(pnum))
        offctrbump = (pupil.shape[0] / 2.0 + 30, pupil.shape[1] / 2.0 + 20.0
                      )  # off-center bump
        ctrbump = (pupil.shape[0] / 2.0, pupil.shape[1] / 2.0)  # central bump
        #quarter wave phase bump, off center
        phase = (2.0 * np.pi / 4.0) * utils.makegauss(
            pupil.shape[0], ctr=offctrbump, sigma=10.0) * pupil
        phase = de_mean(phase, pupil)  # zero mean phase - doesn't change image
        fits.writeto(rfn + "{:1d}__input_truepha.fits".format(pnum),
                     phase,
                     overwrite=True)
        mft = matrixDFT.MatrixFourierTransform()
        imagefield = mft.perform(pupil * np.exp(1j * phase), pupil.shape[0],
                                 pupil.shape[0])
        image = (imagefield * imagefield.conj()).real
        fits.writeto(rfn + "{:1d}__input_img.fits".format(pnum),
                     image / image.sum(),
                     overwrite=True)
        del mft
Ejemplo n.º 4
0
def exer2(odir):
    """ Are you simulating samples or pixels?  Image plane sampling effect """
    # instantiate an mft object:
    ft = matrixDFT.MatrixFourierTransform()

    npup = 100
    radius = 20.0
    fp_size_reselts = 10
    fp_npixels = (4, 8, 16, 32)  
    pupil = utils.makedisk(npup, radius=radius)
    fits.PrimaryHDU(pupil).writeto(odir+"/ex2_pupil.fits", overwrite=True) # write pupil file
    for fpnpix in fp_npixels:
        imagefield = ft.perform(pupil, fp_size_reselts, fpnpix)
        imageintensity = (imagefield*imagefield.conj()).real
        psf = imageintensity / imageintensity.max()  # normalize to peak intensity unity
        zpsf = scipy.ndimage.zoom(psf, 32//fpnpix, order=0)
        fits.PrimaryHDU(zpsf).writeto(odir+"/ex2_nfppix{}_zoom{}.fits".format(fpnpix,32//fpnpix), overwrite=True)
Ejemplo n.º 5
0
def exer3(odir):
    """ What do phase slopes - tilts - in the pupil plane do? """
    # instantiate an mft object:
    ft = matrixDFT.MatrixFourierTransform()
    npup = 100
    radius = 20.0
    fp_size_reselt = 100
    pupil = utils.makedisk(npup, radius=radius)
    tilts = ((0,0),  (0.3,0), (1.0,0), (3.0,0))
    phases = utils.phasearrays(npup, tilts)
    for nt, ph in enumerate(phases):
        pupilarray = pupil * np.exp(1j * ph)
        imagefield = ft.perform(pupilarray, fp_size_reselt, npup)
        image_intensity = (imagefield*imagefield.conj()).real
        psf = image_intensity / image_intensity.max()  # peak intensity unity
        fits.PrimaryHDU(psf).writeto( 
            odir+"/ex3_tilt_a_{0:.3f}_b_{1:.3f}.fits".format(tilts[nt][0],tilts[nt][1]), 
            overwrite=True)
Ejemplo n.º 6
0
def exer1(odir):
    """ Let's get something for nothing if we can!!! """

    # instantiate an mft object:
    ft = matrixDFT.MatrixFourierTransform()

    npup = 100
    radius = 20.0
    fp_size_reselts = (100, 200, 300, 400)
    fp_npixels = (100, 200, 300, 400)  
    pupil = utils.makedisk(npup, radius=radius)
    fits.PrimaryHDU(pupil).writeto(odir+"/ex1_pupil.fits", overwrite=True) # write pupil file
    for (fpr,fpnpix) in zip(fp_npixels,fp_size_reselts):
        imagearray = np.zeros((400,400)) # create same-sized array for all 4 FOV's we calculate.
        imagefield = ft.perform(pupil, fpr, fpnpix)
        imageintensity = (imagefield*imagefield.conj()).real
        psf = imageintensity / imageintensity.max()  # normalize to peak intensity unity
        imagearray[200-fpnpix//2:200+fpnpix//2,200-fpnpix//2:200+fpnpix//2] = psf # center image in largest array size
        fits.PrimaryHDU(imagearray).writeto(odir+"/ex1_nfppix{}_fpsize{}.fits".format(fpnpix,fpr), overwrite=True)
Ejemplo n.º 7
0
def create_input_datafiles_bumps(rfn=None):
    """
        returns: list of mgsdtasets
        Didactic case, no input parameters: create the pupil & monochromatic image 
        on appropriate pixel scales.  
        Pupil and image arrays of same size, ready to FT into each 
        other losslessly.  For real data you'll need to worry about adjusting
        sizes to satify this sampling relation between the two planes.
        For finite bandwidth data image simulation will loop over wavelengths.
        For coarsely sampled pixels image simulation will need to use finer
        sampling and rebin to detector pixel sizes.
        [email protected] Jan 2019
    """
    mft = matrixDFT.MatrixFourierTransform()

    pupilradius = 50
    pupil = utils.makedisk(250, radius=pupilradius)  # D=100 pix, array 250 pix
    pupilindex = np.where(pupil >= 1)
    pupilfn = rfn + "__input_pup.fits"
    fits.writeto(pupilfn, pupil, overwrite=True)

    mgsdatasets = []

    defocus_list = (-12.0, 12.0, -10.0, 10.0, -8.0, 8.0, -6.0, 6.0, -4.0, 4.0,
                    -2.0, 2.0)
    print(defocus_list)
    number_of_d_across_D = range(
        1, 16)  # different aberrations - dia of bump in pupil

    rippleamp = 1.0  # radians, 1/6.3 waves, about 340nm at 2.12 micron  Bump height.  bad var name

    # for a variety of bumps across the pupil:
    for nwaves in number_of_d_across_D:  # preserve var name nwaves from ripple case - bad varname here.
        pupil = fits.getdata(pupilfn)
        mgsdataset = [pupilfn]  # an mgsdataset starts with the pupil file...

        rbump = 4.0 * float(
            pupilradius) / nwaves  # sigma of gaussian bump in pupil
        #print("{:.1e}".format(rbump))
        bump = utils.makegauss(250, ctr=(145.0, 145.0),
                               sigma=rbump)  # D=100 pix, array 250 pix

        rbump = 0.5 * float(pupilradius) / nwaves  # rad of disk bump in pupil
        #print("{:.1e}".format(rbump))
        bump = utils.makedisk(250, radius=rbump,
                              ctr=(145.0, 145.0))  # D=100 pix, array 250 pix

        bump = (1.0 / np.sqrt(2)) * bump / bump[pupilindex].std(
        )  # 0.5 variance aberration, same SR hit
        ripplephase = rippleamp * bump  # bad var name

        phasefn = rfn + "bump_{0:d}acrossD_peak_{1:.1f}_pha.fits".format(
            int(nwaves), rippleamp)
        fits.PrimaryHDU(ripplephase).writeto(phasefn, overwrite=True)
        mgsdataset.append(
            phasefn)  # an mgsdataset now pupil file, phase abberration file,

        # Now create images for each defocus in the list
        #
        # First a utility array, parabola P2V unity over pupil, zero outside pupil
        prad = pupilradius  # for parabola=unity at edge of active pupil 2% < unity
        center = utils.centerpoint(pupil.shape[0])
        unityP2Vparabola = np.fromfunction(
            utils.parabola2d, pupil.shape, cx=center[0],
            cy=center[1]) / (prad * prad) * pupil
        fits.writeto(rfn + "unityP2Vparabola.fits",
                     unityP2Vparabola,
                     overwrite=True)  # sanity check - write it out

        for defoc in defocus_list:  # defoc units are waves, Peak-to-Valley

            defocusphase = unityP2Vparabola * 2 * np.pi * defoc
            aberfn = "pup__bump_defoc_{:.1f}wav.fits".format(defoc)
            fits.writeto(rfn + aberfn, defocusphase, overwrite=True)

            aberfn = rfn + "pup_bump_{0:d}acrossD_peak_{1:.1f}_defoc_{2:.1f}wav.fits".format(
                int(nwaves), rippleamp, defoc)
            imagfn = rfn + "__input_" + "img_bump_{0:d}acrossD_peak_{1:.1f}_defoc_{2:.1f}wav.fits".format(
                int(nwaves), rippleamp, defoc)

            aber = defocusphase + ripplephase
            fits.writeto(aberfn, aber, overwrite=True)

            imagefield = mft.perform(pupil * np.exp(1j * aber), pupil.shape[0],
                                     pupil.shape[0])
            image = (imagefield * imagefield.conj()).real

            fits.writeto(imagfn, image / image.sum(), overwrite=True)

            mgsdataset.append((defoc, imagfn, aberfn))

        mgsdatasets.append(mgsdataset)

    # Prepare a quicklook at signal in the pairs of defocussed images:
    side = 2.0  # inches, quicklook at curvatue signal imshow

    ndefoc = len(defocus_list) // 2
    nspatfreq = len(number_of_d_across_D)
    magnif = 2.0
    fig = plt.figure(1, (nspatfreq * magnif, ndefoc * magnif))
    grid = ImageGrid(
        fig,
        111,  # similar to subplot(111)
        nrows_ncols=(ndefoc, nspatfreq),  # creates 2x2 grid of axes
        axes_pad=0.02,  # pad between axes in inch.
    )
    i = 0
    iwav = 0
    for nwaves in number_of_d_across_D:
        ifoc = 0
        maxlist = []
        for defoc in defocus_list:  # defoc units are waves, Peak-to-Valley
            if defoc > 0:
                imagfn_pos = rfn + "__input_" + "img_bump_{0:d}acrossD_peak_{1:.1f}_defoc_{2:.1f}wav.fits".format(
                    int(nwaves), rippleamp, defoc)
                imagfn_neg = rfn + "__input_" + "img_bump_{0:d}acrossD_peak_{1:.1f}_defoc_{2:.1f}wav.fits".format(
                    int(nwaves), rippleamp, -defoc)
                datapos = fits.getdata(imagfn_pos).flatten()
                dataneg = fits.getdata(imagfn_neg).flatten()
                quicklook = (datapos - dataneg[::-1]).reshape((250, 250)) * (
                    defoc * defoc)  # normalize to equal brightness signal
                maxlist.append(quicklook.max())
                print("max {:.1e}".format(quicklook.max())
                      )  # print me out and fix the limits for imshow by hand.
                #fits.writeto(imagfn_pos.replace("img","qlk"), quicklook, overwrite=True)
                i = iwav + (ndefoc - ifoc - 1) * nspatfreq
                grid[i].imshow(
                    quicklook,
                    origin='lower',
                    cmap=plt.get_cmap(
                        'ocean'),  # RdBu, gist_rainbow, ocean, none
                    vmin=-3.0e-3,
                    vmax=3.0e-3)  # The AxesGrid object work as a list of axes.
                grid[i].set_xticks([])
                grid[i].set_yticks([])
                grid[i].text(20,
                             220,
                             "D/{:d} dia bump".format(int(nwaves + 1)),
                             color='y',
                             weight='bold')
                grid[i].text(20,
                             20,
                             "+/-{:d}w PV".format(int(defoc)),
                             color='w',
                             weight='bold')
                #print('iwav', iwav, 'ifoc', ifoc, 'i:', i)
                ifoc += 1
        iwav += 1
    strtop = "Wavefront signal from piston phase bumps of different diameters vs. defocus either side of focus"
    strbot = "Anand S. 2019, after Dean & Bowers, JOSA A 2003 (figs. 4 & 7)"
    fig.text(0.02, 0.94, strtop, fontsize=18, weight='bold')
    fig.text(0.02, 0.05, strbot, fontsize=14)
    plt.tight_layout()
    plt.savefig("DeanBowers2003_signal_vs_defocus_bump.png",
                dpi=150,
                pad_inches=1.0)
    plt.show()

    #print("Unity P-V parabola:", arraystats(unityP2Vparabola))
    """
    for dataset in mgsdatasets: 
        print("MGS data set: pupilfn, aber, (defoc/PVwaves, imagefn, defoc+aber), (repeats)")
        for thing in dataset: 
            print("\t", thing)
        print("")
    """
    return mgsdatasets
Ejemplo n.º 8
0
def create_input_datafiles(rfn=None):
    """
        returns: list of mgsdtasets
            pupilfn: name of pupil file
        Pupil and image data, true (zero mean) phase map (rad) 
        No de-tilting of the thase done.
        Didactic case, no input parameters: create the pupil & monochromatic image 
        on appropriate pixel scales.  
        Pupil and image arrays of same size, ready to FT into each 
        other losslessly.  For real data you'll need to worry about adjusting
        sizes to satify this sampling relation between the two planes.
        For finite bandwidth data image simulation will loop over wavelengths.
        For coarsely sampled pixels image simulation will need to use finer
        sampling and rebin to detector pixel sizes.
        [email protected] Jan 2019
    """
    mft = matrixDFT.MatrixFourierTransform()

    pupilradius = 50
    pupil = utils.makedisk(250, radius=pupilradius)  # D=100 pix, array 250 pix
    pupilfn = rfn + "__input_pup.fits"
    fits.writeto(pupilfn, pupil, overwrite=True)

    mgsdatasets = []

    dfoc_max = 12
    nfoci = 8  # number of defocus steps, in geo prog
    ffac = pow(10, np.log10(dfoc_max) / nfoci)
    defocus_list = []
    for i in range(nfoci):
        defocus_list.append(ffac)
        defocus_list.append(-ffac)
        ffac *= pow(10, np.log10(dfoc_max) / nfoci)
    defocus_list.reverse()
    defocus_list = (-12.0, 12.0, -10.0, 10.0, -8.0, 8.0, -6.0, 6.0, -4.0, 4.0,
                    -2.0, 2.0)
    print(defocus_list)
    number_of_waves_across_D = range(
        1, 16)  # different aberrations - number of waves across pupil
    print(number_of_waves_across_D)

    rippleamp = 1.0  # radians, 1/6.3 waves, about 340nm at 2.12 micron
    ripplepha = 30.0  # degrees, just for fun
    rippleangle = 15.0  # degrees

    # for a variety of ripples across the pupil:
    for nwaves in number_of_waves_across_D:
        pupil = fits.getdata(pupilfn)
        mgsdataset = [pupilfn]  # an mgsdataset starts with the pupil file...
        spatialwavelen = 2.0 * pupilradius / nwaves
        khat = np.array((np.sin(rippleangle * np.pi / 180.0),
                         np.cos(rippleangle * np.pi / 180.0)))  # unit vector
        kwavedata = np.fromfunction(utils.kwave2d,
                                    pupil.shape,
                                    spatialwavelen=spatialwavelen,
                                    center=utils.centerpoint(pupil.shape[0]),
                                    offset=ripplepha,
                                    khat=khat)
        ripplephase = pupil * rippleamp * kwavedata
        #imagefield = ft.perform(pupilarray, fp_size_reselt, npup)  # remove this
        #image_intensity = (imagefield*imagefield.conj()).real  # remove this
        #psf = image_intensity / image_intensity.sum()  # total intensity unity  # remove this

        phasefn = rfn + "ripple_{0:d}acrossD_peak_{1:.1f}_pha.fits".format(
            int(nwaves), rippleamp)
        fits.PrimaryHDU(ripplephase).writeto(phasefn, overwrite=True)
        mgsdataset.append(
            phasefn)  # an mgsdataset now pupil file, phase abberration file,

        # Now create images for each defocus in the list
        #
        # First a utility array, parabola P2V unity over pupil, zero outside pupil
        prad = pupilradius  # for parabola=unity at edge of active pupil 2% < unity
        center = utils.centerpoint(pupil.shape[0])
        unityP2Vparabola = np.fromfunction(
            utils.parabola2d, pupil.shape, cx=center[0],
            cy=center[1]) / (prad * prad) * pupil
        fits.writeto(rfn + "unityP2Vparabola.fits",
                     unityP2Vparabola,
                     overwrite=True)  # sanity check - write it out

        for defoc in defocus_list:  # defoc units are waves, Peak-to-Valley

            defocusphase = unityP2Vparabola * 2 * np.pi * defoc
            aberfn = "pup_defoc_{:.1f}wav.fits".format(defoc)
            fits.writeto(rfn + aberfn, defocusphase, overwrite=True)

            aberfn = rfn + "pup_ripple_{0:d}acrossD_peak_{1:.1f}_defoc_{2:.1f}wav.fits".format(
                int(nwaves), rippleamp, defoc)
            imagfn = rfn + "__input_" + "img_ripple_{0:d}acrossD_peak_{1:.1f}_defoc_{2:.1f}wav.fits".format(
                int(nwaves), rippleamp, defoc)

            aber = defocusphase + ripplephase
            #fits.writeto(aberfn, aber, overwrite=True)

            imagefield = mft.perform(pupil * np.exp(1j * aber), pupil.shape[0],
                                     pupil.shape[0])
            image = (imagefield * imagefield.conj()).real

            fits.writeto(imagfn, image / image.sum(), overwrite=True)

            mgsdataset.append((defoc, imagfn, aberfn))

        mgsdatasets.append(mgsdataset)
        """
        phase = de_mean(phase, pupil) # zero mean phase - doesn't change image
        fits.writeto(rfn+"{:1d}__input_truepha.fits".format(pnum), phase, overwrite=True)
        mft = matrixDFT.MatrixFourierTransform()
        imagefield = mft.perform(pupil * np.exp(1j*phase), pupil.shape[0], pupil.shape[0])
        image =  (imagefield*imagefield.conj()).real 
        fits.writeto(rfn+"{:1d}__input_img.fits".format(pnum), image/image.sum(), overwrite=True)
        del mft
        """

    # Prepare a quicklook at signal in the pairs of defocussed images:
    side = 2.0  # inches, quicklook at curvatue signal imshow

    ndefoc = len(defocus_list) // 2
    nspatfreq = len(number_of_waves_across_D)
    magnif = 2.0
    fig = plt.figure(1, (nspatfreq * magnif, ndefoc * magnif))
    grid = ImageGrid(
        fig,
        111,  # similar to subplot(111)
        nrows_ncols=(ndefoc, nspatfreq),  # creates 2x2 grid of axes
        axes_pad=0.02,  # pad between axes in inch.
    )
    i = 0
    iwav = 0
    for nwaves in number_of_waves_across_D:
        ifoc = 0
        maxlist = []
        for defoc in defocus_list:  # defoc units are waves, Peak-to-Valley
            if defoc > 0:
                imagfn_pos = rfn + "__input_" + "img_ripple_{0:d}acrossD_peak_{1:.1f}_defoc_{2:.1f}wav.fits".format(
                    int(nwaves), rippleamp, defoc)
                imagfn_neg = rfn + "__input_" + "img_ripple_{0:d}acrossD_peak_{1:.1f}_defoc_{2:.1f}wav.fits".format(
                    int(nwaves), rippleamp, -defoc)
                datapos = fits.getdata(imagfn_pos).flatten()
                dataneg = fits.getdata(imagfn_neg).flatten()
                quicklook = (datapos - dataneg[::-1]).reshape((250, 250)) * (
                    defoc * defoc)  # normalize to equal brightness signal
                maxlist.append(quicklook.max())
                #print("max {:.1e}".format(quicklook.max()))
                #fits.writeto(imagfn_pos.replace("img","qlk"), quicklook, overwrite=True)
                i = iwav + (ndefoc - ifoc - 1) * nspatfreq
                grid[i].imshow(
                    quicklook,
                    origin='lower',
                    cmap=plt.get_cmap(
                        'ocean'),  # RdBu, gist_rainbow, ocean, none
                    vmin=-1.3e-2,
                    vmax=1.3e-2)  # The AxesGrid object work as a list of axes.
                grid[i].set_xticks([])
                grid[i].set_yticks([])
                grid[i].text(20,
                             220,
                             "{:d} ripples ax D".format(int(nwaves)),
                             color='y',
                             weight='bold')
                grid[i].text(20,
                             20,
                             "+/-{:d}w PV".format(int(defoc)),
                             color='w',
                             weight='bold')

                ifoc += 1
        iwav += 1
    strtop = "Wavefront signal from phase ripples across the pupil vs. defocus either side of focus"
    strbot = "Anand S. 2019, illustrating Dean & Bowers, JOSA A 2003 (figs. 4 & 7)"
    fig.text(0.02, 0.94, strtop, fontsize=18, weight='bold')
    fig.text(0.02, 0.05, strbot, fontsize=14)
    plt.tight_layout()
    plt.savefig("DeanBowers2003_signal_vs_defocus_ripple.pdf",
                dpi=150,
                pad_inches=1.0)
    plt.show()

    #print("Unity P-V parabola:", arraystats(unityP2Vparabola))
    """
    for dataset in mgsdatasets: 
        print("MGS data set: pupilfn, aber, (defoc/PVwaves, imagefn, defoc+aber), (repeats)")
        for thing in dataset: 
            print("\t", thing)
        print("")
    """
    return mgsdatasets
Ejemplo n.º 9
0
def exer6(odir):
    """ Coronagraph train, no optimization for speed.  
    2nd order BLC, didactic example, fftlike """
    # instantiate an mft object:
    ft = matrixDFT.MatrixFourierTransform()

    npup = 250 # Size of all arrays
    radius = 50.0

    # Numerical reselts in DFT setup cf telescope reselts:
    # reselts of telescope - here its 0.4 reselts per DFT output image pixel if npup=250,radius=50.
    dftpixel = 2.0 * radius / npup
    # Jinc first zero in reselts of telescope...
    firstzero_optical_reselts = 10.0
    firstzero_numericalpixels = firstzero_optical_reselts / dftpixel
    print("Jinc firstzero_numericalpixels", firstzero_numericalpixels)

    jinc = np.fromfunction(utils.Jinc, (npup,npup),
                           c=utils.centerpoint(npup),
                           scale=firstzero_numericalpixels)
    fpm_blc2ndorder = 1 - jinc*jinc
    print("Jinc fpm min = ", fpm_blc2ndorder.min(), 
          "Jinc fpm max = ", fpm_blc2ndorder.max())

    # Pupil, Pupilphase, Apodizer, FP intensity, Intensity after FPM, 
    # Lyot intensity, Lyot Stop, Post-Lyot Stop Intensity, Final image.
    #
    # Set up optical train for a typical Lyot style or phase mask coronagraph:
    Cordict = {
        "Pupil": utils.makedisk(npup, radius=radius),
        "Pupilphase": None,
        "Apodizer": None,
        "FPintensity": None,
        "FPM": fpm_blc2ndorder,
        "LyotIntensity": None,
        "LyotStop":  utils.makedisk(npup, radius=41),
        "PostLyotStopIntensity": None,
        "FinalImage": None,
        "ContrastImage": None}


    # Propagate through the coronagraph train...
    # Start with perfect incoming plane wave, no aberrations
    efield = Cordict["Pupil"]
    # Put in phase aberrations:
    if Cordict["Pupilphase"] is not None:
        efield *= np.exp(1j*Cordict["Pupilphase"])
    # Apodize the entrance pupil:
    if Cordict["Apodizer"] is not None:
        efield *= Cordict["Apodizer"]
    # PROPAGATE TO FIRST FOCAL PLANE:
    efield = ft.perform(efield, npup, npup)
    # Store FPM intensity:
    Cordict["FPintensity"] = (efield * efield.conj()).real

    # Save no-Cor efield for normalization of cor image by peak of no-FPM image
    efield_NC = efield.copy()
    # Multiply by FPM transmission function
    # Lyot style - zero in center, phase mask style: zero integral over domain
    efield *=  Cordict["FPM"]

    # PROPAGATE TO LYOT PLANE:
    efield_NC = ft.perform(efield_NC, npup, npup)
    efield = ft.perform(efield, npup, npup)
    # Save Cor Lyot intensity;
    Cordict["LyotIntensity"] = (efield * efield.conj()).real
    # Apply Lyot stop:
    if Cordict["LyotStop"] is not None: efield_NC *= Cordict["LyotStop"]
    if Cordict["LyotStop"] is not None: efield *= Cordict["LyotStop"]
    # Save Cor Lyot intensity after applying Lyot stop;
    Cordict["PostLyotStopIntensity"] = (efield * efield.conj()).real

    # PROPAGATE TO FINAL IMAGE PLANE:
    efield_NC = ft.perform(efield_NC, npup, npup)
    efield = ft.perform(efield, npup, npup)
    final_image_intensity_NC = (efield_NC * efield_NC.conj()).real
    final_image_intensity = (efield * efield.conj()).real
    Cordict["FinalImage"] = (efield * efield.conj()).real
    Cordict["ContrastImage"] = (efield * efield.conj()).real / final_image_intensity_NC.max()

    # Write our coronagraph planes:
    planenames, cube = corcube(Cordict)
    # write planemames as fits keywords
    print(odir+"/ex6_BLC_2ndOrder.fits")
    fits.PrimaryHDU(cube).writeto(odir+"/ex6_BLC_2ndOrder.fits", overwrite=True)
    fobj = fits.open(odir+"/ex6_BLC_2ndOrder.fits")
    fobj[0].header["Pupil"] = 1
    fobj[0].header["FPI"] = (2, "focal plane Intensity")
    fobj[0].header["FPM"] = (3, "focal plane mask")
    fobj[0].header["LyotIntn"] = (4, "Lyot Intensity")
    fobj[0].header["LyotStop"] = 5
    fobj[0].header["PostLyot"] = (6, "Post Lyot Stop Intensity")
    fobj[0].header["CorIm"] = (7, "Raw cor image")
    fobj[0].header["Contrast"] = (8, "Cor image in contrast units")
    fobj.writeto(odir+"/ex6_BLC_2ndOrder.fits", overwrite=True)