Ejemplo n.º 1
0
def star_profiles(ps):
    # Run an example CCD, 292604-N4, with fairly large difference vs PS1.

    # python -c "from astrometry.util.fits import *; T = merge_tables([fits_table('/project/projectdirs/desiproc/dr3/tractor/244/tractor-244%s.fits' % b) for b in ['2p065','4p065', '7p065']]); T.writeto('tst-cat.fits')"
    # python legacypipe/forced_photom_decam.py --save-data tst-data.fits --save-model tst-model.fits 292604 N4 tst-cat.fits tst-phot.fits

    # -> tst-{model,data,phot}.fits

    datafn = 'tst-data.fits'
    modfn = 'tst-model.fits'
    photfn = 'tst-phot.fits'
    catfn = 'tst-cat.fits'

    img = fitsio.read(datafn)
    mod = fitsio.read(modfn)
    phot = fits_table(photfn)
    cat = fits_table(catfn)
    print(len(phot), 'forced-photometry results')
    margin = 25
    phot.cut((phot.x > 0 + margin) * (phot.x < 2046 - margin) *
             (phot.y > 0 + margin) * (phot.y < 4096 - margin))
    print(len(phot), 'in bounds')

    cmap = dict([((b, o), i)
                 for i, (b, o) in enumerate(zip(cat.brickname, cat.objid))])
    I = np.array(
        [cmap.get((b, o), -1) for b, o in zip(phot.brickname, phot.objid)])
    print(np.sum(I >= 0), 'forced-phot matched cat')
    phot.type = cat.type[I]

    wcs = Sip(datafn)

    phot.ra, phot.dec = wcs.pixelxy2radec(phot.x + 1, phot.y + 1)
    phot.cut(np.argsort(phot.flux))

    phot.sn = phot.flux * np.sqrt(phot.flux_ivar)

    phot.cut(phot.sn > 5)
    print(len(phot), 'with S/N > 5')

    ps1 = ps1cat(ccdwcs=wcs)
    stars = ps1.get_stars()
    print(len(stars), 'PS1 sources')
    # Now cut to just *stars* with good colors
    stars.gicolor = stars.median[:, 0] - stars.median[:, 2]
    keep = (stars.gicolor > 0.4) * (stars.gicolor < 2.7)
    stars.cut(keep)
    print(len(stars), 'PS1 stars with good colors')
    stars.cut(np.minimum(stars.stdev[:, 1], stars.stdev[:, 2]) < 0.05)
    print(len(stars), 'PS1 stars with min stdev(r,i) < 0.05')
    I, J, d = match_radec(phot.ra, phot.dec, stars.ra, stars.dec, 1. / 3600.)
    print(len(I), 'matches')

    plt.clf()
    ha = dict(histtype='step', bins=20, range=(0, 100), normed=True)
    plt.hist(phot.flux, color='b', **ha)
    plt.hist(phot.flux[I], color='r', **ha)
    ps.savefig()

    plt.clf()
    plt.hist(phot.flux * np.sqrt(phot.flux_ivar), bins=100, range=(-10, 50))
    plt.xlabel('Flux S/N')
    ps.savefig()

    K = np.argsort(phot.flux[I])
    I = I[K]
    J = J[K]

    ix = np.round(phot.x).astype(int)
    iy = np.round(phot.y).astype(int)
    sz = 10

    P = np.flatnonzero(phot.type == 'PSF ')
    print(len(P), 'PSFs')

    imed = len(P) / 2
    i1 = int(len(P) * 0.75)
    i2 = int(len(P) * 0.25)
    N = 401

    allmods = []
    allimgs = []

    for II, tt in [  #(I[:len(I)/2], 'faint matches to PS1'),
            #(I[len(I)/2:], 'bright matches to PS1'),
            #(P[i2: i2+N], '25th pct PSFs'),
            #(P[imed: imed+N], 'median PSFs'),
            #(P[i1: i1+N], '75th pct PSFs'),
            #(P[-25:], 'brightest PSFs'),
        (P[i2:imed], '2nd quartile of PSFs'),
        (P[imed:i1], '3rd quartile of PSFs'),
            #(P[:len(P)/2], 'faint half of PSFs'),
            #(P[len(P)/2:], 'bright half of PSFs'),
    ]:
        imgs = []
        mods = []
        shimgs = []
        shmods = []
        imgsum = modsum = 0

        #plt.clf()
        for i in II:

            from astrometry.util.util import lanczos_shift_image

            dy = phot.y[i] - iy[i]
            dx = phot.x[i] - ix[i]

            sub = img[iy[i] - sz:iy[i] + sz + 1, ix[i] - sz:ix[i] + sz + 1]
            shimg = lanczos_shift_image(sub, -dx, -dy)

            sub = mod[iy[i] - sz:iy[i] + sz + 1, ix[i] - sz:ix[i] + sz + 1]
            shmod = lanczos_shift_image(sub, -dx, -dy)

            iyslice = img[iy[i], ix[i] - sz:ix[i] + sz + 1]
            myslice = mod[iy[i], ix[i] - sz:ix[i] + sz + 1]
            ixslice = img[iy[i] - sz:iy[i] + sz + 1, ix[i]]
            mxslice = mod[iy[i] - sz:iy[i] + sz + 1, ix[i]]
            mx = iyslice.max()
            # plt.plot(iyslice/mx, 'b-', alpha=0.1)
            # plt.plot(myslice/mx, 'r-', alpha=0.1)
            # plt.plot(ixslice/mx, 'b-', alpha=0.1)
            # plt.plot(mxslice/mx, 'r-', alpha=0.1)

            siyslice = shimg[sz, :]
            sixslice = shimg[:, sz]
            smyslice = shmod[sz, :]
            smxslice = shmod[:, sz]

            shimgs.append(siyslice / mx)
            shimgs.append(sixslice / mx)
            shmods.append(smyslice / mx)
            shmods.append(smxslice / mx)

            imgs.append(iyslice / mx)
            imgs.append(ixslice / mx)
            mods.append(myslice / mx)
            mods.append(mxslice / mx)

            imgsum = imgsum + ixslice + iyslice
            modsum = modsum + mxslice + myslice

        # plt.ylim(-0.1, 1.1)
        # plt.title(tt)
        # ps.savefig()
        mimg = np.median(np.array(imgs), axis=0)
        mmod = np.median(np.array(mods), axis=0)
        mshim = np.median(np.array(shimgs), axis=0)
        mshmo = np.median(np.array(shmods), axis=0)

        allmods.append(mshmo)
        allimgs.append(mshim)

        plt.clf()
        # plt.plot(mimg, 'b-')
        # plt.plot(mmod, 'r-')
        plt.plot(mshim, 'g-')
        plt.plot(mshmo, 'm-')

        plt.ylim(-0.1, 1.1)
        plt.title(tt + ': median; sums %.3f/%.3f' %
                  (np.sum(mimg), np.sum(mmod)))
        ps.savefig()

        # plt.clf()
        # mx = imgsum.max()
        # plt.plot(imgsum/mx, 'b-')
        # plt.plot(modsum/mx, 'r-')
        # plt.ylim(-0.1, 1.1)
        # plt.title(tt + ': sum')
        # ps.savefig()

        plt.clf()
        plt.plot((mimg + 0.01) / (mmod + 0.01), 'k-')
        plt.plot((imgsum / mx + 0.01) / (modsum / mx + 0.01), 'g-')
        plt.plot((mshim + 0.01) / (mshmo + 0.01), 'm-')
        plt.ylabel('(img + 0.01) / (mod + 0.01)')
        plt.title(tt)
        ps.savefig()

    iq2, iq3 = allimgs
    mq2, mq3 = allmods
    plt.clf()

    plt.plot(iq2, 'r-')
    plt.plot(mq2, 'm-')

    plt.plot(iq3, 'b-')
    plt.plot(mq3, 'g-')

    plt.title('Q2 vs Q3')
    ps.savefig()
Ejemplo n.º 2
0
def star_profiles(ps):
    # Run an example CCD, 292604-N4, with fairly large difference vs PS1.
    
    # python -c "from astrometry.util.fits import *; T = merge_tables([fits_table('/project/projectdirs/desiproc/dr3/tractor/244/tractor-244%s.fits' % b) for b in ['2p065','4p065', '7p065']]); T.writeto('tst-cat.fits')"
    # python legacypipe/forced_photom_decam.py --save-data tst-data.fits --save-model tst-model.fits 292604 N4 tst-cat.fits tst-phot.fits

    # -> tst-{model,data,phot}.fits

    datafn = 'tst-data.fits'
    modfn = 'tst-model.fits'
    photfn = 'tst-phot.fits'
    catfn = 'tst-cat.fits'
    
    img = fitsio.read(datafn)
    mod = fitsio.read(modfn)
    phot = fits_table(photfn)
    cat = fits_table(catfn)
    print(len(phot), 'forced-photometry results')
    margin = 25
    phot.cut((phot.x > 0+margin) * (phot.x < 2046-margin) *
             (phot.y > 0+margin) * (phot.y < 4096-margin))
    print(len(phot), 'in bounds')

    cmap = dict([((b,o),i) for i,(b,o) in enumerate(zip(cat.brickname, cat.objid))])
    I = np.array([cmap.get((b,o), -1) for b,o in zip(phot.brickname, phot.objid)])
    print(np.sum(I >= 0), 'forced-phot matched cat')
    phot.type = cat.type[I]

    wcs = Sip(datafn)
    
    phot.ra,phot.dec = wcs.pixelxy2radec(phot.x+1, phot.y+1)
    phot.cut(np.argsort(phot.flux))

    phot.sn = phot.flux * np.sqrt(phot.flux_ivar)

    phot.cut(phot.sn > 5)
    print(len(phot), 'with S/N > 5')
    
    ps1 = ps1cat(ccdwcs=wcs)
    stars = ps1.get_stars()
    print(len(stars), 'PS1 sources')
    # Now cut to just *stars* with good colors
    stars.gicolor = stars.median[:,0] - stars.median[:,2]
    keep = (stars.gicolor > 0.4) * (stars.gicolor < 2.7)
    stars.cut(keep)
    print(len(stars), 'PS1 stars with good colors')
    stars.cut(np.minimum(stars.stdev[:,1], stars.stdev[:,2]) < 0.05)
    print(len(stars), 'PS1 stars with min stdev(r,i) < 0.05')
    I,J,d = match_radec(phot.ra, phot.dec, stars.ra, stars.dec, 1./3600.)
    print(len(I), 'matches')

    plt.clf()
    ha=dict(histtype='step', bins=20, range=(0,100), normed=True)
    plt.hist(phot.flux, color='b', **ha)
    plt.hist(phot.flux[I], color='r', **ha)
    ps.savefig()

    plt.clf()
    plt.hist(phot.flux * np.sqrt(phot.flux_ivar), bins=100,
             range=(-10, 50))
    plt.xlabel('Flux S/N')
    ps.savefig()
    
    K = np.argsort(phot.flux[I])
    I = I[K]
    J = J[K]

    ix = np.round(phot.x).astype(int)
    iy = np.round(phot.y).astype(int)
    sz = 10

    P = np.flatnonzero(phot.type == 'PSF ')
    print(len(P), 'PSFs')

    imed = len(P)/2
    i1 = int(len(P) * 0.75)
    i2 = int(len(P) * 0.25)
    N = 401

    allmods = []
    allimgs = []
    
    for II,tt in [#(I[:len(I)/2], 'faint matches to PS1'),
        #(I[len(I)/2:], 'bright matches to PS1'),
        #(P[i2: i2+N], '25th pct PSFs'),
        #(P[imed: imed+N], 'median PSFs'),
        #(P[i1: i1+N], '75th pct PSFs'),
        #(P[-25:], 'brightest PSFs'),
        (P[i2:imed], '2nd quartile of PSFs'),
        (P[imed:i1], '3rd quartile of PSFs'),
        #(P[:len(P)/2], 'faint half of PSFs'),
        #(P[len(P)/2:], 'bright half of PSFs'),
                  ]:
        imgs = []
        mods = []
        shimgs = []
        shmods = []
        imgsum = modsum = 0

        #plt.clf()
        for i in II:

            from astrometry.util.util import lanczos_shift_image
            
            dy = phot.y[i] - iy[i]
            dx = phot.x[i] - ix[i]

            sub = img[iy[i]-sz : iy[i]+sz+1, ix[i]-sz : ix[i]+sz+1]
            shimg = lanczos_shift_image(sub, -dx, -dy)

            sub = mod[iy[i]-sz : iy[i]+sz+1, ix[i]-sz : ix[i]+sz+1]
            shmod = lanczos_shift_image(sub, -dx, -dy)

            iyslice = img[iy[i], ix[i]-sz : ix[i]+sz+1]
            myslice = mod[iy[i], ix[i]-sz : ix[i]+sz+1]
            ixslice = img[iy[i]-sz : iy[i]+sz+1, ix[i]]
            mxslice = mod[iy[i]-sz : iy[i]+sz+1, ix[i]]
            mx = iyslice.max()
            # plt.plot(iyslice/mx, 'b-', alpha=0.1)
            # plt.plot(myslice/mx, 'r-', alpha=0.1)
            # plt.plot(ixslice/mx, 'b-', alpha=0.1)
            # plt.plot(mxslice/mx, 'r-', alpha=0.1)

            siyslice = shimg[sz, :]
            sixslice = shimg[:, sz]
            smyslice = shmod[sz, :]
            smxslice = shmod[:, sz]

            shimgs.append(siyslice/mx)
            shimgs.append(sixslice/mx)
            shmods.append(smyslice/mx)
            shmods.append(smxslice/mx)

            imgs.append(iyslice/mx)
            imgs.append(ixslice/mx)
            mods.append(myslice/mx)
            mods.append(mxslice/mx)

            imgsum = imgsum + ixslice + iyslice
            modsum = modsum + mxslice + myslice

        # plt.ylim(-0.1, 1.1)
        # plt.title(tt)
        # ps.savefig()
        mimg = np.median(np.array(imgs), axis=0)
        mmod = np.median(np.array(mods), axis=0)
        mshim = np.median(np.array(shimgs), axis=0)
        mshmo = np.median(np.array(shmods), axis=0)

        allmods.append(mshmo)
        allimgs.append(mshim)
        
        plt.clf()
        # plt.plot(mimg, 'b-')
        # plt.plot(mmod, 'r-')
        plt.plot(mshim, 'g-')
        plt.plot(mshmo, 'm-')
        
        plt.ylim(-0.1, 1.1)
        plt.title(tt + ': median; sums %.3f/%.3f' % (np.sum(mimg), np.sum(mmod)))
        ps.savefig()
        
        # plt.clf()
        # mx = imgsum.max()
        # plt.plot(imgsum/mx, 'b-')
        # plt.plot(modsum/mx, 'r-')
        # plt.ylim(-0.1, 1.1)
        # plt.title(tt + ': sum')
        # ps.savefig()

        plt.clf()
        plt.plot((mimg + 0.01) / (mmod + 0.01), 'k-')
        plt.plot((imgsum/mx + 0.01) / (modsum/mx + 0.01), 'g-')
        plt.plot((mshim + 0.01) / (mshmo + 0.01), 'm-')
        plt.ylabel('(img + 0.01) / (mod + 0.01)')
        plt.title(tt)
        ps.savefig()
        

    iq2,iq3 = allimgs
    mq2,mq3 = allmods
    plt.clf()

    plt.plot(iq2, 'r-')
    plt.plot(mq2, 'm-')

    plt.plot(iq3, 'b-')
    plt.plot(mq3, 'g-')

    plt.title('Q2 vs Q3')
    ps.savefig()
Ejemplo n.º 3
0
    ps.savefig()

    # Subsample the PSF via resampling
    from astrometry.util.util import lanczos_shift_image

    scale = 2
    sh, sw = ph * scale, pw * scale
    subpixpsf = np.zeros((sh, sw))
    for ix in np.arange(scale):
        for iy in np.arange(scale):
            dx = ix / float(scale)
            dy = iy / float(scale)
            if ix == 0 and iy == 0:
                subpixpsf[0::scale, 0::scale] = pixpsf
                continue
            shift = lanczos_shift_image(pixpsf, -dx, -dy, order=5)
            subpixpsf[iy::scale, ix::scale] = shift

    # Evaluate a R_e = 1 pixel deVauc on the native pixel grid, using
    # the Gaussian approximation
    xx, yy = np.meshgrid(np.arange(pw), np.arange(ph))
    center = pw / 2
    r2 = (xx - center)**2 + (yy - center)**2
    pixgal = np.zeros_like(pixpsf)

    from demo import DevGalaxy
    gal = DevGalaxy()

    for a, v in zip(gal.amp, gal.var):
        vv = v * gal_re**2
        ## FIXME ??? prefactors?
Ejemplo n.º 4
0
def lopass(psfex, ps3):
    ### Lopass
    #plt.figure(2)

    fig_rect = 3
    fig_square = 2

    H, W = 256, 256

    theta = 110
    psfim = psfex.instantiateAt(0, 0)

    T2 = 15
    psfim = psfim[T2:-T2, T2:-T2]
    ph, pw = psfim.shape
    cx, cy = pw / 2, ph / 2

    egal = EllipseE.fromRAbPhi(4., 0.3, theta)
    gal = ExpGalaxy(PixPos(0, 0), Flux(100.), egal)

    pixpsf = PixelizedPSF(psfim)
    halfsize = 10.
    P, (px0, py0), (pH,
                    pW), (w, v) = pixpsf.getFourierTransform(0., 0., halfsize)

    data = np.zeros((H, W), np.float32)
    tinypsf = NCircularGaussianPSF([1e-6], [1.])
    img = Image(data=data, invvar=np.ones_like(data), psf=tinypsf)

    #amix = gal._getAffineProfile(img, cx, cy)
    amix = gal._getAffineProfile(img, 0, 0)
    Fmine = amix.getFourierTransform(w, v)

    print('Amix amps:', amix.amp, 'sum', amix.amp.sum())

    ima = dict(ticks=False, cmap=antigray)
    fima = dict(ticks=False, cmap='Blues')
    rima = dict(ticks=False, cmap='Greens')
    iima = dict(ticks=False, cmap='Reds')

    def diffshow(D, **ima):
        mx = np.max(np.abs(D))
        dimshow(D, vmin=-mx, vmax=mx, **ima)

    # Move galaxy to center of image.
    gal.pos.x = pH / 2.
    gal.pos.y = pW / 2.
    print('tiny PSF conv galaxy')
    print('pH,pW:', pH, pW)
    tinyp = gal.getModelPatch(img)
    tinypad = np.zeros((pH, pW))
    tinyp.addTo(tinypad)

    # #print('w range:', np.min(w), np.max(w))
    # #print('v range:', np.min(v), np.max(v))
    # w2 = np.linspace(2.*np.min(w), 2.*np.max(w), len(w)*2-1)
    # v2 = np.linspace(2.*np.min(v), 2.*np.max(v), len(v)*2-1)
    # # print('w:', w)
    # # print('w2:', w2)
    # # print('v:', v)
    # # print('v2:', v2)
    # # [v2,w2]
    # Fmine2 = amix.getFourierTransform(w2, v2)
    #
    # # print('w2', len(w2), 'v2', len(v2), 'Fmine2', Fmine2.shape)
    #
    # I = np.flatnonzero((w2 >= np.min(w)) * (w2 <= np.max(w)))
    # J = np.flatnonzero((v2 >= np.min(v)) * (v2 <= np.max(v)))
    # # print('w', len(w), 'v', len(v), 'Fmine', Fmine.shape)
    # # print('I', len(I), 'J', len(J))
    #
    # print('Sub-sum Fmine2:', Fmine2[J,:][:,I].real.sum())
    #
    # # w3 = np.linspace(3.*np.min(w), 3.*np.max(w), len(w)*3-2)
    # # v3 = np.linspace(3.*np.min(v), 3.*np.max(v), len(v)*3-2)
    # # print('w:', w)
    # # print('w3:', w3)
    # # print('v:', v)
    # # print('v3:', v3)
    # # # [v2,w2]
    # # Fmine3 = amix.getFourierTransform(w3, v3)
    # # print('Fmine3.real sum', Fmine3.real.sum())
    # #
    # # print('Folded Fmine3.real sum', Fmine3.real.sum() + Fmine3[:,1:].real.sum())
    #
    # #print('amix:', amix)
    # #print('amix means:', amix.mean)
    #
    # # My method, Fourier transform with twice the frequency range
    # plt.clf()
    # dimshow(np.hypot(Fmine2.real, Fmine2.imag), **fima)
    # plt.title('Fmine2')
    # ps3.savefig()
    #
    # #for va in amix.var:
    # #    e = EllipseE.fromCovariance(va)
    # ax = plt.axis()
    # for k in range(amix.K):
    #     Cinv = np.linalg.inv(amix.var[k,:,:])
    #     Cinv *= (4. * np.pi**2)
    #     e = EllipseE.fromCovariance(Cinv)
    #     B = e.getRaDecBasis() * 3600.
    #     angle = np.linspace(0, 2.*np.pi, 90)
    #     cc = np.cos(angle)
    #     ss = np.sin(angle)
    #     xx = B[0,0] * cc + B[0,1] * ss
    #     yy = B[1,0] * cc + B[1,1] * ss
    #     f2H,f2W = Fmine2.shape
    #     plt.plot(xx, f2H/2. + yy, 'r-', lw=2)
    #
    #     plt.plot(xx, 1.5 * f2H + yy, 'r--', lw=2)
    #     plt.plot(xx, -0.5 * f2H + yy, 'r--', lw=2)
    #
    # plt.axis(ax)
    # ps3.savefig()
    #
    # # plt.clf()
    # # dimshow(Fmine2.real, **rima)
    # # print('Real range:', Fmine2.real.min(), Fmine2.real.max())
    # # ps3.savefig()
    # # plt.clf()
    # # dimshow(Fmine2.imag, **iima)
    # # print('Imag range:', Fmine2.imag.min(), Fmine2.imag.max())
    # # ps3.savefig()
    #
    # print('Fmine2.real sum', Fmine2.real.sum())
    # print('Fmine.real sum', Fmine.real.sum())

    # plt.clf()
    # dimshow(tinypad, **ima)
    # ps3.savefig()
    #
    # Rotated to be zero-centered.
    tinypad2 = np.fft.fftshift(tinypad)
    # plt.clf()
    # dimshow(tinypad2, **ima)
    # ps3.savefig()
    #
    # my = np.fft.irfft2(Fmine, s=(pH,pW))
    # plt.clf()
    # dimshow(my, **ima)
    # ps3.savefig()

    # Galaxy conv tiny PSF
    #Ftiny = np.fft.rfft2(tinypad)
    Ftiny = np.fft.rfft2(tinypad2)
    #print('Tinypad shape', tinypad.shape)
    tH, tW = tinypad.shape
    Ftiny /= (tH * np.pi)

    print('Ftiny.real sum', Ftiny.real.sum())

    #print('Folded Ftiny.real sum', Ftiny.real.sum() + Ftiny[:,1:].real.sum())

    plt.clf()
    dimshow(np.fft.fftshift(np.hypot(Ftiny.real, Ftiny.imag), axes=(0, )),
            vmin=0,
            vmax=1.1,
            **fima)
    #plt.colorbar()
    #ps3.savefig()
    plt.savefig('lopass-naive.pdf')

    # Ftiny2 = np.fft.fft2(tinypad2)
    # Ftiny2 /= (tH * np.pi)
    # print('Ftiny2.real sum', Ftiny2.real.sum())
    #
    # plt.clf()
    # dimshow(np.fft.fftshift(np.hypot(Ftiny2.real, Ftiny2.imag)),
    #         **fima)
    # plt.colorbar()
    # ps3.savefig()

    # plt.clf()
    # dimshow(np.fft.fftshift(Ftiny.real, axes=(0,)), **rima)
    # ps3.savefig()
    # plt.clf()
    # dimshow(np.fft.fftshift(Ftiny.imag, axes=(0,)), **iima)
    # ps3.savefig()
    print('Ftiny Real range:', Ftiny.real.min(), Ftiny.real.max())
    print('Ftiny Imag range:', Ftiny.imag.min(), Ftiny.imag.max())

    # Mine, at regular frequencies
    plt.clf()
    dimshow(np.fft.fftshift(np.hypot(Fmine.real, Fmine.imag), axes=(0, )),
            vmin=0,
            vmax=1.1,
            **fima)
    #plt.colorbar()
    plt.savefig('lopass-mine.pdf')

    plt.figure(fig_square)
    # Pixel-space galaxy plots
    PM = np.fft.irfft2(Fmine, s=(pH, pW))
    PT = np.fft.irfft2(Ftiny, s=(tH, tW))
    mx = max(PM.max(), PT.max())
    print('PM sum', PM.sum())
    print('Max', PM.max())
    PM = np.fft.fftshift(PM)
    plt.clf()
    dimshow(PM, vmin=0, vmax=mx, **ima)
    plt.savefig('lopass-mine-pix.pdf')
    #ps3.savefig()

    print('PT sum', PT.sum())
    PT = np.fft.fftshift(PT)
    plt.clf()
    dimshow(PT, vmin=0, vmax=mx, **ima)
    #ps3.savefig()
    plt.savefig('lopass-naive-pix.pdf')
    plt.figure(fig_rect)

    # plt.clf()
    # dimshow(np.fft.fftshift(Fmine.real, axes=(0,)), **rima)
    # ps3.savefig()
    #
    # plt.clf()
    # dimshow(np.fft.fftshift(Fmine.imag, axes=(0,)), **iima)
    # ps3.savefig()

    print('Fmine Real range:', Fmine.real.min(), Fmine.real.max())
    print('Fmine Imag range:', Fmine.imag.min(), Fmine.imag.max())

    plt.clf()
    dimshow(
        np.fft.fftshift(np.hypot(Ftiny.real - Fmine.real,
                                 Ftiny.imag - Fmine.imag),
                        axes=(0, )), **fima)
    #plt.colorbar()
    plt.savefig('lopass-diff.pdf')

    # plt.clf()
    # dimshow(np.fft.fftshift(Ftiny.real - Fmine.real, axes=(0,)), **rima)
    # ps3.savefig()
    #
    # plt.clf()
    # dimshow(np.fft.fftshift(Ftiny.imag - Fmine.imag, axes=(0,)), **iima)
    # ps3.savefig()

    diff = Ftiny - Fmine
    print('diff Real range:', diff.real.min(), diff.real.max())
    print('diff Imag range:', diff.imag.min(), diff.imag.max())

    print('Fmine sum:', np.hypot(Fmine.real, Fmine.imag).sum())
    print('Ftiny sum:', np.hypot(Ftiny.real, Ftiny.imag).sum())

    ax = plt.axis()
    ## HACK -- 5th contour is confusing-looking
    for k in range(2, amix.K):
        Cinv = np.linalg.inv(amix.var[k, :, :])
        Cinv *= (4. * np.pi**2)
        e = EllipseE.fromCovariance(Cinv)
        B = e.getRaDecBasis() * 3600.
        angle = np.linspace(0, 2. * np.pi, 90)
        cc = np.cos(angle)
        ss = np.sin(angle)
        xx = B[0, 0] * cc + B[0, 1] * ss
        yy = B[1, 0] * cc + B[1, 1] * ss
        fsH, fsW = Fmine.shape
        plt.plot(xx, fsH / 2. + yy, 'r-', lw=2)

        plt.plot(xx, 1.5 * fsH + yy, 'r--', lw=2)
        plt.plot(xx, -0.5 * fsH + yy, 'r--', lw=2)
    plt.axis(ax)
    plt.savefig('lopass-diff-ell.pdf')
    #ps3.savefig()

    plt.clf()
    dimshow(np.log10(
        np.maximum(
            np.fft.fftshift(np.hypot(Ftiny.real, Ftiny.imag), axes=(0, )),
            1e-6)),
            vmin=-3,
            vmax=0,
            **fima)
    #plt.colorbar()
    #plt.title('log Ftiny')
    #ps3.savefig()
    plt.savefig('lopass-naive-log.pdf')

    plt.clf()
    dimshow(np.log10(
        np.maximum(
            np.fft.fftshift(np.hypot(Fmine.real, Fmine.imag), axes=(0, )),
            1e-6)),
            vmin=-3,
            vmax=0,
            **fima)
    #plt.colorbar()
    #plt.title('log Fmine')
    #ps3.savefig()
    plt.savefig('lopass-mine-log.pdf')

    # plt.clf()
    # dimshow(np.log10(np.maximum(
    #     np.hypot(Fmine2.real, Fmine2.imag),
    #     1e-6)),
    #     vmin=-3, vmax=0, **fima)
    # plt.colorbar()
    # plt.title('log Fmine2')
    # ps3.savefig()

    # Subsample the PSF via resampling
    from astrometry.util.util import lanczos_shift_image

    # dxlist,dylist = [],[]
    # scales = [2,4,8,16]
    # for scale in scales:
    #
    #     sh,sw = ph*scale, pw*scale
    #     subpsfim = np.zeros((sh,sw))
    #     step = 1./float(scale)
    #     for ix in np.arange(scale):
    #         for iy in np.arange(scale):
    #             dx = ix * step
    #             dy = iy * step
    #             #dx = 0.5 + (ix - 0.5) * step
    #             #dy = 0.5 + (iy - 0.5) * step
    #             #if ix == 0 and iy == 0:
    #             #    subpsfim[0::scale, 0::scale] = psfim
    #             #    continue
    #             shift = lanczos_shift_image(psfim, -dx, -dy, order=5)
    #             subpsfim[iy::scale, ix::scale] = shift
    #
    #     # HACK -clamp edges to zero to counter possible weird lanczos edge issues?
    #     subpsfim[:2,:] = 0
    #     subpsfim[:,:2] = 0
    #     subpsfim[-2:,:] = 0
    #     subpsfim[:,-2:] = 0
    #
    #     print('ph,pw, scale', ph,pw,scale)
    #     print('sh,sw', sh,sw)
    #     print('Subpsfim shape', subpsfim.shape)
    #     subpixpsf = PixelizedPSF(subpsfim[:-1,:-1])
    #     SP,(px0,py0),(spH,spW),(sw,sv) = subpixpsf.getFourierTransform(
    #         0., 0., scale*halfsize)
    #
    #     wcs = NullWCS()
    #     wcs.pixscale /= scale
    #     print('subsampling image: set pixscale', wcs.pixscale)
    #     print('WCS:', wcs)
    #
    #     subdata=np.zeros((scale*H,scale*W), np.float32)
    #     subimg = Image(data=subdata, invvar=np.ones_like(subdata), psf=tinypsf,
    #                    wcs=wcs)
    #
    #     # Move galaxy to center of image.
    #     gal.pos.x = scale*pH/2.
    #     gal.pos.y = scale*pW/2.
    #
    #     subtinyp = gal.getModelPatch(subimg)
    #     subtinypad = np.zeros((scale*pH,scale*pW))
    #     subtinyp.addTo(subtinypad)
    #     # Rotated to be zero-centered.
    #     subtinypad2 = np.fft.fftshift(subtinypad)
    #
    #     Fsub = np.fft.rfft2(subtinypad2)
    #     tH,tW = subtinypad.shape
    #     Fsub /= (tH * np.pi)
    #     Fsub *= scale
    #
    #     sz = scale * 32
    #     SG = np.fft.irfft2(Fsub * SP, s=(sz,sz))
    #
    #     # Bin the subsampled ones...
    #     BSG = bin_image(SG, scale)
    #     BSG /= (scale**2)
    #
    #     sz1 = 32
    #     MG = np.fft.irfft2(Fmine * P, s=(sz1,sz1))
    #
    #     print('MG:')
    #     x1,y1 = measure(MG)
    #     #mx.append(x1)
    #     #my.append(y1)
    #     print('BSG:')
    #     x2,y2 = measure(BSG)
    #     #sx.append(x2)
    #     #sy.append(y2)
    #     dxlist.append(x2 - x1)
    #     dylist.append(y2 - y1)
    #
    #     print('shift', x2-x1, y2-y1)
    #     shift = lanczos_shift_image(BSG, -(x2-x1), -(y2-y1), order=5)
    #     x3,y3 = measure(shift)
    #     print('shifted:', x3-x1, y3-y1)
    #
    #
    # plt.clf()
    # plt.plot(scales, dxlist, 'bo-')
    # plt.plot(scales, dylist, 'ro-')
    # ps3.savefig()
    # print('scales = np.array(', scales, ')')
    # print('dx = np.array(', dxlist, ')')
    # print('dy = np.array(', dylist, ')')
    #
    # return

    scale = 8
    sh, sw = ph * scale, pw * scale
    subpsfim = np.zeros((sh, sw))
    step = 1. / float(scale)
    for ix in np.arange(scale):
        for iy in np.arange(scale):
            dx = ix * step
            dy = iy * step
            #dx = 0.5 + (ix - 0.5) * step
            #dy = 0.5 + (iy - 0.5) * step
            #if ix == 0 and iy == 0:
            #    subpsfim[0::scale, 0::scale] = psfim
            #    continue
            shift = lanczos_shift_image(psfim, -dx, -dy, order=5)
            subpsfim[iy::scale, ix::scale] = shift

    # HACK -clamp edges to zero to counter possible weird lanczos edge issues?
    subpsfim[:2, :] = 0
    subpsfim[:, :2] = 0
    subpsfim[-2:, :] = 0
    subpsfim[:, -2:] = 0

    plt.clf()
    plt.subplot(1, 2, 1)
    dimshow(psfim)
    plt.subplot(1, 2, 2)
    dimshow(subpsfim)
    ps3.savefig()

    print('SubPSF image:', subpsfim.shape)
    subpixpsf = PixelizedPSF(subpsfim[:-1, :-1])
    SP, (px0, py0), (spH, spW), (sw, sv) = subpixpsf.getFourierTransform(
        0., 0., scale * halfsize)

    print('SP shape', SP.shape)

    wcs = NullWCS()
    wcs.pixscale /= scale
    print('subsampling image: set pixscale', wcs.pixscale)
    print('WCS:', wcs)

    subdata = np.zeros((scale * H, scale * W), np.float32)
    subimg = Image(data=subdata,
                   invvar=np.ones_like(subdata),
                   psf=tinypsf,
                   wcs=wcs)

    # Move galaxy to center of image.
    gal.pos.x = scale * pH / 2.
    gal.pos.y = scale * pW / 2.

    subtinyp = gal.getModelPatch(subimg)
    subtinypad = np.zeros((scale * pH, scale * pW))
    subtinyp.addTo(subtinypad)
    # Rotated to be zero-centered.
    subtinypad2 = np.fft.fftshift(subtinypad)

    plt.clf()
    dimshow(subtinypad2, **ima)
    plt.title('subtinypad2')
    ps3.savefig()

    plt.clf()
    dimshow(tinypad2, **ima)
    plt.title('tinypad2')
    ps3.savefig()

    Fsub = np.fft.rfft2(subtinypad2)
    tH, tW = subtinypad.shape
    Fsub /= (tH * np.pi)
    Fsub *= scale

    fima2 = fima.copy()
    fima2.update(vmin=0, vmax=1.1)

    Fsub_orig = Fsub.copy()

    # Trim Fsub to same size (63,33) vs (64,33)
    #h1,w1 = Fsub.shape
    #hm2,wm2 = Fmine2.shape
    #Fsub = Fsub[:hm2,:]

    plt.clf()
    dimshow(np.fft.fftshift(np.hypot(Fsub.real, Fsub.imag), axes=(0, )),
            **fima2)
    plt.colorbar()
    plt.title('Fsub')
    ps3.savefig()

    print('Fsub sum:', np.hypot(Fsub.real, Fsub.imag).sum())
    print('Fsub Real range:', Fsub.real.min(), Fsub.real.max())
    print('Fsub Imag range:', Fsub.imag.min(), Fsub.imag.max())

    pH, pW = subtinypad2.shape
    wt = np.fft.rfftfreq(pW)
    vt = np.fft.fftfreq(pH)
    # print('wsub:', len(wt), 'min/max', wt.min(), wt.max())
    # print('vsub:', len(vt), 'min/max', vt.min(), vt.max())

    df = np.abs(w[1] - w[0])
    w2b = np.arange(scale * (len(w) - 1) + 1) * df + scale * np.min(w)
    v2b = np.arange(scale * len(v)) * df + scale * np.min(v)
    # print('w2:', w2)
    # print('w2b:', w2b)
    # print('v2:', v2)
    # print('v2b:', v2b)
    Fmine2b = amix.getFourierTransform(w2b, v2b)
    # -> shape len(v2b),len(w2b)

    print('Fmine2b shape', Fmine2b.shape)
    print('Fmine2b sum:', np.hypot(Fmine2b.real, Fmine2b.imag).sum())
    print('Fmine2b Real range:', Fmine2b.real.min(), Fmine2b.real.max())
    print('Fmine2b Imag range:', Fmine2b.imag.min(), Fmine2b.imag.max())

    print('Fsub_orig shape:', Fsub_orig.shape)

    # # My method, Fourier transform with twice the frequency range
    # plt.clf()
    # dimshow(np.hypot(Fmine2.real, Fmine2.imag), **fima2)
    # plt.colorbar()
    # plt.title('Fmine2')
    # ps3.savefig()
    #
    # diff = np.fft.fftshift(Fsub, axes=(0,)) - Fmine2
    # print('diff Real range:', diff.real.min(), diff.real.max())
    # print('diff Imag range:', diff.imag.min(), diff.imag.max())
    #
    # plt.clf()
    # dimshow(np.hypot(diff.real, diff.imag), **fima)
    # plt.colorbar()
    # plt.title('Fsub - Fmine2')
    # ps3.savefig()

    diff2 = np.fft.fftshift(Fsub_orig, axes=(0, )) - Fmine2b
    print('diff2 Real range:', diff.real.min(), diff.real.max())
    print('diff2 Imag range:', diff.imag.min(), diff.imag.max())

    plt.clf()
    dimshow(np.hypot(diff2.real, diff2.imag), **fima)
    plt.colorbar()
    plt.title('Fsub - Fmine2b')
    ps3.savefig()

    plt.clf()
    dimshow(diff2.real, **rima)
    plt.colorbar()
    plt.title('real(Fsub - Fmine2b)')
    ps3.savefig()

    print('Ftiny:', Ftiny.shape)
    print('P:', P.shape)
    print('Fsub:', Fsub.shape)
    print('SP:', SP.shape)
    print('Fmine2b:', Fmine2b.shape)

    #sz1 = 32
    #sz = 64
    sz1 = 32
    sz = scale * 32

    plt.clf()
    plt.subplot(2, 2, 1)
    dimshow(Ftiny.real, **rima)
    plt.colorbar()
    plt.subplot(2, 2, 2)
    dimshow(Ftiny.imag, **iima)
    plt.colorbar()
    plt.subplot(2, 2, 3)
    dimshow(P.real, **rima)
    plt.colorbar()
    plt.subplot(2, 2, 4)
    dimshow(P.imag, **iima)
    plt.colorbar()
    plt.suptitle('Ftiny, P')
    ps3.savefig()

    PG = np.fft.irfft2(Ftiny * P, s=(sz1, sz1))
    print('PG', PG.dtype, PG.shape)
    plt.clf()
    dimshow(PG, **ima)
    plt.colorbar()
    plt.title('PG')
    ps3.savefig()

    #P,(px0,py0),(pH,pW),(w,v) = pixpsf.getFourierTransform(0., 0., halfsize)
    #Fmine = amix.getFourierTransform(w, v)

    plt.clf()
    plt.subplot(2, 2, 1)
    dimshow(Fmine.real, **rima)
    plt.colorbar()
    plt.subplot(2, 2, 2)
    dimshow(Fmine.imag, **iima)
    plt.colorbar()
    plt.subplot(2, 2, 3)
    dimshow(P.real, **rima)
    plt.colorbar()
    plt.subplot(2, 2, 4)
    dimshow(P.imag, **iima)
    plt.colorbar()
    plt.suptitle('Fmine, P')
    ps3.savefig()

    MG = np.fft.irfft2(Fmine * P, s=(sz1, sz1))
    print('MG', MG.dtype, MG.shape)
    plt.clf()
    dimshow(MG, **ima)
    plt.colorbar()
    plt.title('MG')
    ps3.savefig()

    plt.clf()
    diffshow(PG - MG, **ima)
    plt.colorbar()
    plt.title('PG - MG')
    ps3.savefig()

    plt.clf()
    plt.subplot(2, 2, 1)
    dimshow(Fsub.real, **rima)
    plt.colorbar()
    plt.subplot(2, 2, 2)
    dimshow(Fsub.imag, **iima)
    plt.colorbar()
    plt.subplot(2, 2, 3)
    dimshow(SP.real, **rima)
    plt.colorbar()
    plt.subplot(2, 2, 4)
    dimshow(SP.imag, **iima)
    plt.colorbar()
    plt.suptitle('Fsub, SP')
    ps3.savefig()

    SG = np.fft.irfft2(Fsub * SP, s=(sz, sz))
    print('SG', SG.dtype, SG.shape)
    plt.clf()
    dimshow(SG, **ima)
    plt.colorbar()
    plt.title('SG')
    ps3.savefig()

    Fmine2c = np.fft.fftshift(Fmine2b, axes=(0, ))

    plt.clf()
    plt.subplot(2, 2, 1)
    dimshow(Fmine2c.real, **rima)
    plt.colorbar()
    plt.subplot(2, 2, 2)
    dimshow(Fmine2c.imag, **iima)
    plt.colorbar()
    plt.subplot(2, 2, 3)
    dimshow(SP.real, **rima)
    plt.colorbar()
    plt.subplot(2, 2, 4)
    dimshow(SP.imag, **iima)
    plt.colorbar()
    plt.suptitle('Fmine2c, SP')
    ps3.savefig()

    MG2 = np.fft.irfft2(Fmine2c * SP, s=(sz, sz))
    print('MG2', MG2.dtype, MG2.shape)
    plt.clf()
    dimshow(MG2, **ima)
    plt.colorbar()
    plt.title('MG2')
    ps3.savefig()

    plt.clf()
    diffshow(SG - MG2, **ima)
    plt.colorbar()
    plt.title('SG - MG2')
    ps3.savefig()

    # Bin the subsampled ones...
    BSG = bin_image(SG, scale)
    BSG /= (scale**2)

    print('MG:')
    x1, y1 = measure(MG)
    print('BSG:')
    x2, y2 = measure(BSG)

    shiftBSG = lanczos_shift_image(BSG, -(x2 - x1), -(y2 - y1), order=5)

    plt.clf()
    dimshow(BSG, **ima)
    plt.colorbar()
    plt.title('BSG')
    ps3.savefig()

    plt.clf()
    diffshow(BSG - MG, **ima)
    plt.colorbar()
    plt.title('BSG - MG')
    ps3.savefig()

    plt.clf()
    diffshow(shiftBSG - MG, **ima)
    plt.colorbar()
    plt.title('shiftBSG - MG')
    ps3.savefig()
Ejemplo n.º 5
0
    ps.savefig()

    # Subsample the PSF via resampling
    from astrometry.util.util import lanczos_shift_image

    scale = 2
    sh,sw = ph*scale, pw*scale
    subpixpsf = np.zeros((sh,sw))
    for ix in np.arange(scale):
        for iy in np.arange(scale):
            dx = ix / float(scale)
            dy = iy / float(scale)
            if ix == 0 and iy == 0:
                subpixpsf[0::scale, 0::scale] = pixpsf
                continue
            shift = lanczos_shift_image(pixpsf, -dx, -dy, order=5)
            subpixpsf[iy::scale, ix::scale] = shift

    # Evaluate a R_e = 1 pixel deVauc on the native pixel grid, using
    # the Gaussian approximation
    xx,yy = np.meshgrid(np.arange(pw), np.arange(ph))
    center = pw/2
    r2 = (xx - center)**2 + (yy - center)**2
    pixgal = np.zeros_like(pixpsf)
    
    from demo import DevGalaxy
    gal = DevGalaxy()
    
    for a,v in zip(gal.amp, gal.var):
        vv = v * gal_re**2
        ## FIXME ??? prefactors?
Ejemplo n.º 6
0
def lopass(psfex, ps3):
    ### Lopass
    #plt.figure(2)

    fig_rect = 3
    fig_square = 2
    
    H,W = 256,256


    theta = 110
    psfim = psfex.instantiateAt(0,0)

    T2 = 15
    psfim = psfim[T2:-T2,T2:-T2]
    ph,pw = psfim.shape
    cx,cy = pw/2, ph/2
    
    egal = EllipseE.fromRAbPhi(4., 0.3, theta)
    gal = ExpGalaxy(PixPos(0,0), Flux(100.), egal)

    pixpsf = PixelizedPSF(psfim)
    halfsize = 10.
    P,(px0,py0),(pH,pW),(w,v) = pixpsf.getFourierTransform(0., 0., halfsize)

    data=np.zeros((H,W), np.float32)
    tinypsf = NCircularGaussianPSF([1e-6], [1.])
    img = Image(data=data, invvar=np.ones_like(data), psf=tinypsf)

    #amix = gal._getAffineProfile(img, cx, cy)
    amix = gal._getAffineProfile(img, 0, 0)
    Fmine = amix.getFourierTransform(w, v)

    print('Amix amps:', amix.amp, 'sum', amix.amp.sum())

    ima = dict(ticks=False, cmap=antigray)
    fima = dict(ticks=False, cmap='Blues')
    rima = dict(ticks=False, cmap='Greens')
    iima = dict(ticks=False, cmap='Reds')

    def diffshow(D, **ima):
        mx = np.max(np.abs(D))
        dimshow(D, vmin=-mx, vmax=mx, **ima)
    
    # Move galaxy to center of image.
    gal.pos.x = pH/2.
    gal.pos.y = pW/2.
    print('tiny PSF conv galaxy')
    print('pH,pW:', pH,pW)
    tinyp = gal.getModelPatch(img)
    tinypad = np.zeros((pH,pW))
    tinyp.addTo(tinypad)

    # #print('w range:', np.min(w), np.max(w))
    # #print('v range:', np.min(v), np.max(v))
    # w2 = np.linspace(2.*np.min(w), 2.*np.max(w), len(w)*2-1)
    # v2 = np.linspace(2.*np.min(v), 2.*np.max(v), len(v)*2-1)
    # # print('w:', w)
    # # print('w2:', w2)
    # # print('v:', v)
    # # print('v2:', v2)
    # # [v2,w2]
    # Fmine2 = amix.getFourierTransform(w2, v2)
    # 
    # # print('w2', len(w2), 'v2', len(v2), 'Fmine2', Fmine2.shape)
    # 
    # I = np.flatnonzero((w2 >= np.min(w)) * (w2 <= np.max(w)))
    # J = np.flatnonzero((v2 >= np.min(v)) * (v2 <= np.max(v)))
    # # print('w', len(w), 'v', len(v), 'Fmine', Fmine.shape)
    # # print('I', len(I), 'J', len(J))
    # 
    # print('Sub-sum Fmine2:', Fmine2[J,:][:,I].real.sum())
    # 
    # # w3 = np.linspace(3.*np.min(w), 3.*np.max(w), len(w)*3-2)
    # # v3 = np.linspace(3.*np.min(v), 3.*np.max(v), len(v)*3-2)
    # # print('w:', w)
    # # print('w3:', w3)
    # # print('v:', v)
    # # print('v3:', v3)
    # # # [v2,w2]
    # # Fmine3 = amix.getFourierTransform(w3, v3)
    # # print('Fmine3.real sum', Fmine3.real.sum())
    # # 
    # # print('Folded Fmine3.real sum', Fmine3.real.sum() + Fmine3[:,1:].real.sum())
    # 
    # #print('amix:', amix)
    # #print('amix means:', amix.mean)
    # 
    # # My method, Fourier transform with twice the frequency range
    # plt.clf()
    # dimshow(np.hypot(Fmine2.real, Fmine2.imag), **fima)
    # plt.title('Fmine2')
    # ps3.savefig()
    # 
    # #for va in amix.var:
    # #    e = EllipseE.fromCovariance(va)
    # ax = plt.axis()
    # for k in range(amix.K):
    #     Cinv = np.linalg.inv(amix.var[k,:,:])
    #     Cinv *= (4. * np.pi**2)
    #     e = EllipseE.fromCovariance(Cinv)
    #     B = e.getRaDecBasis() * 3600.
    #     angle = np.linspace(0, 2.*np.pi, 90)
    #     cc = np.cos(angle)
    #     ss = np.sin(angle)
    #     xx = B[0,0] * cc + B[0,1] * ss
    #     yy = B[1,0] * cc + B[1,1] * ss
    #     f2H,f2W = Fmine2.shape
    #     plt.plot(xx, f2H/2. + yy, 'r-', lw=2)
    # 
    #     plt.plot(xx, 1.5 * f2H + yy, 'r--', lw=2)
    #     plt.plot(xx, -0.5 * f2H + yy, 'r--', lw=2)
    # 
    # plt.axis(ax)
    # ps3.savefig()
    # 
    # # plt.clf()
    # # dimshow(Fmine2.real, **rima)
    # # print('Real range:', Fmine2.real.min(), Fmine2.real.max())
    # # ps3.savefig()
    # # plt.clf()
    # # dimshow(Fmine2.imag, **iima)
    # # print('Imag range:', Fmine2.imag.min(), Fmine2.imag.max())
    # # ps3.savefig()
    # 
    # print('Fmine2.real sum', Fmine2.real.sum())
    # print('Fmine.real sum', Fmine.real.sum())

    # plt.clf()
    # dimshow(tinypad, **ima)
    # ps3.savefig()
    # 
    # Rotated to be zero-centered.
    tinypad2 = np.fft.fftshift(tinypad)
    # plt.clf()
    # dimshow(tinypad2, **ima)
    # ps3.savefig()
    # 
    # my = np.fft.irfft2(Fmine, s=(pH,pW))
    # plt.clf()
    # dimshow(my, **ima)
    # ps3.savefig()

    # Galaxy conv tiny PSF
    #Ftiny = np.fft.rfft2(tinypad)
    Ftiny = np.fft.rfft2(tinypad2)
    #print('Tinypad shape', tinypad.shape)
    tH,tW = tinypad.shape
    Ftiny /= (tH * np.pi)

    print('Ftiny.real sum', Ftiny.real.sum())

    #print('Folded Ftiny.real sum', Ftiny.real.sum() + Ftiny[:,1:].real.sum())

    plt.clf()
    dimshow(np.fft.fftshift(np.hypot(Ftiny.real, Ftiny.imag), axes=(0,)),
            vmin=0, vmax=1.1, **fima)
    #plt.colorbar()
    #ps3.savefig()
    plt.savefig('lopass-naive.pdf')
    
    # Ftiny2 = np.fft.fft2(tinypad2)
    # Ftiny2 /= (tH * np.pi)
    # print('Ftiny2.real sum', Ftiny2.real.sum())
    # 
    # plt.clf()
    # dimshow(np.fft.fftshift(np.hypot(Ftiny2.real, Ftiny2.imag)),
    #         **fima)
    # plt.colorbar()
    # ps3.savefig()

    # plt.clf()
    # dimshow(np.fft.fftshift(Ftiny.real, axes=(0,)), **rima)
    # ps3.savefig()
    # plt.clf()
    # dimshow(np.fft.fftshift(Ftiny.imag, axes=(0,)), **iima)
    # ps3.savefig()
    print('Ftiny Real range:', Ftiny.real.min(), Ftiny.real.max())
    print('Ftiny Imag range:', Ftiny.imag.min(), Ftiny.imag.max())

    # Mine, at regular frequencies
    plt.clf()
    dimshow(np.fft.fftshift(np.hypot(Fmine.real, Fmine.imag), axes=(0,)),
            vmin=0, vmax=1.1, **fima)
    #plt.colorbar()
    plt.savefig('lopass-mine.pdf')

    plt.figure(fig_square)
    # Pixel-space galaxy plots
    PM = np.fft.irfft2(Fmine, s=(pH,pW))
    PT = np.fft.irfft2(Ftiny, s=(tH,tW))
    mx = max(PM.max(), PT.max())
    print('PM sum', PM.sum())
    print('Max', PM.max())
    PM = np.fft.fftshift(PM)
    plt.clf()
    dimshow(PM, vmin=0, vmax=mx, **ima)
    plt.savefig('lopass-mine-pix.pdf')
    #ps3.savefig()
    
    print('PT sum', PT.sum())
    PT = np.fft.fftshift(PT)
    plt.clf()
    dimshow(PT, vmin=0, vmax=mx, **ima)
    #ps3.savefig()
    plt.savefig('lopass-naive-pix.pdf')
    plt.figure(fig_rect)

    
    # plt.clf()
    # dimshow(np.fft.fftshift(Fmine.real, axes=(0,)), **rima)
    # ps3.savefig()
    # 
    # plt.clf()
    # dimshow(np.fft.fftshift(Fmine.imag, axes=(0,)), **iima)
    # ps3.savefig()

    print('Fmine Real range:', Fmine.real.min(), Fmine.real.max())
    print('Fmine Imag range:', Fmine.imag.min(), Fmine.imag.max())


    plt.clf()
    dimshow(np.fft.fftshift(np.hypot(Ftiny.real - Fmine.real,
                                     Ftiny.imag - Fmine.imag), axes=(0,)), **fima)
    #plt.colorbar()
    plt.savefig('lopass-diff.pdf')


    # plt.clf()
    # dimshow(np.fft.fftshift(Ftiny.real - Fmine.real, axes=(0,)), **rima)
    # ps3.savefig()
    # 
    # plt.clf()
    # dimshow(np.fft.fftshift(Ftiny.imag - Fmine.imag, axes=(0,)), **iima)
    # ps3.savefig()

    diff = Ftiny - Fmine
    print('diff Real range:', diff.real.min(), diff.real.max())
    print('diff Imag range:', diff.imag.min(), diff.imag.max())

    print('Fmine sum:', np.hypot(Fmine.real, Fmine.imag).sum())
    print('Ftiny sum:', np.hypot(Ftiny.real, Ftiny.imag).sum())

    ax = plt.axis()
    ## HACK -- 5th contour is confusing-looking
    for k in range(2, amix.K):
        Cinv = np.linalg.inv(amix.var[k,:,:])
        Cinv *= (4. * np.pi**2)
        e = EllipseE.fromCovariance(Cinv)
        B = e.getRaDecBasis() * 3600.
        angle = np.linspace(0, 2.*np.pi, 90)
        cc = np.cos(angle)
        ss = np.sin(angle)
        xx = B[0,0] * cc + B[0,1] * ss
        yy = B[1,0] * cc + B[1,1] * ss
        fsH,fsW = Fmine.shape
        plt.plot(xx, fsH/2. + yy, 'r-', lw=2)

        plt.plot(xx, 1.5 * fsH + yy, 'r--', lw=2)
        plt.plot(xx, -0.5 * fsH + yy, 'r--', lw=2)
    plt.axis(ax)
    plt.savefig('lopass-diff-ell.pdf')
    #ps3.savefig()


    plt.clf()
    dimshow(np.log10(np.maximum(
        np.fft.fftshift(np.hypot(Ftiny.real, Ftiny.imag), axes=(0,)),
        1e-6)),
        vmin=-3, vmax=0, **fima)
    #plt.colorbar()
    #plt.title('log Ftiny')
    #ps3.savefig()
    plt.savefig('lopass-naive-log.pdf')
    
    plt.clf()
    dimshow(np.log10(np.maximum(
        np.fft.fftshift(np.hypot(Fmine.real, Fmine.imag), axes=(0,)),
        1e-6)),
        vmin=-3, vmax=0, **fima)
    #plt.colorbar()
    #plt.title('log Fmine')
    #ps3.savefig()
    plt.savefig('lopass-mine-log.pdf')

    # plt.clf()
    # dimshow(np.log10(np.maximum(
    #     np.hypot(Fmine2.real, Fmine2.imag),
    #     1e-6)),
    #     vmin=-3, vmax=0, **fima)
    # plt.colorbar()
    # plt.title('log Fmine2')
    # ps3.savefig()
        


    # Subsample the PSF via resampling
    from astrometry.util.util import lanczos_shift_image


    # dxlist,dylist = [],[]
    # scales = [2,4,8,16]
    # for scale in scales:
    #     
    #     sh,sw = ph*scale, pw*scale
    #     subpsfim = np.zeros((sh,sw))
    #     step = 1./float(scale)
    #     for ix in np.arange(scale):
    #         for iy in np.arange(scale):
    #             dx = ix * step
    #             dy = iy * step
    #             #dx = 0.5 + (ix - 0.5) * step
    #             #dy = 0.5 + (iy - 0.5) * step
    #             #if ix == 0 and iy == 0:
    #             #    subpsfim[0::scale, 0::scale] = psfim
    #             #    continue
    #             shift = lanczos_shift_image(psfim, -dx, -dy, order=5)
    #             subpsfim[iy::scale, ix::scale] = shift
    # 
    #     # HACK -clamp edges to zero to counter possible weird lanczos edge issues?
    #     subpsfim[:2,:] = 0
    #     subpsfim[:,:2] = 0
    #     subpsfim[-2:,:] = 0
    #     subpsfim[:,-2:] = 0
    # 
    #     print('ph,pw, scale', ph,pw,scale)
    #     print('sh,sw', sh,sw)
    #     print('Subpsfim shape', subpsfim.shape)
    #     subpixpsf = PixelizedPSF(subpsfim[:-1,:-1])
    #     SP,(px0,py0),(spH,spW),(sw,sv) = subpixpsf.getFourierTransform(
    #         0., 0., scale*halfsize)
    # 
    #     wcs = NullWCS()
    #     wcs.pixscale /= scale
    #     print('subsampling image: set pixscale', wcs.pixscale)
    #     print('WCS:', wcs)
    # 
    #     subdata=np.zeros((scale*H,scale*W), np.float32)
    #     subimg = Image(data=subdata, invvar=np.ones_like(subdata), psf=tinypsf,
    #                    wcs=wcs)
    # 
    #     # Move galaxy to center of image.
    #     gal.pos.x = scale*pH/2.
    #     gal.pos.y = scale*pW/2.
    #     
    #     subtinyp = gal.getModelPatch(subimg)
    #     subtinypad = np.zeros((scale*pH,scale*pW))
    #     subtinyp.addTo(subtinypad)
    #     # Rotated to be zero-centered.
    #     subtinypad2 = np.fft.fftshift(subtinypad)
    #     
    #     Fsub = np.fft.rfft2(subtinypad2)
    #     tH,tW = subtinypad.shape
    #     Fsub /= (tH * np.pi)
    #     Fsub *= scale
    #     
    #     sz = scale * 32
    #     SG = np.fft.irfft2(Fsub * SP, s=(sz,sz))
    # 
    #     # Bin the subsampled ones...
    #     BSG = bin_image(SG, scale)
    #     BSG /= (scale**2)
    # 
    #     sz1 = 32
    #     MG = np.fft.irfft2(Fmine * P, s=(sz1,sz1))
    # 
    #     print('MG:')
    #     x1,y1 = measure(MG)
    #     #mx.append(x1)
    #     #my.append(y1)
    #     print('BSG:')
    #     x2,y2 = measure(BSG)
    #     #sx.append(x2)
    #     #sy.append(y2)
    #     dxlist.append(x2 - x1)
    #     dylist.append(y2 - y1)
    # 
    #     print('shift', x2-x1, y2-y1)
    #     shift = lanczos_shift_image(BSG, -(x2-x1), -(y2-y1), order=5)
    #     x3,y3 = measure(shift)
    #     print('shifted:', x3-x1, y3-y1)
    # 
    #     
    # plt.clf()
    # plt.plot(scales, dxlist, 'bo-')
    # plt.plot(scales, dylist, 'ro-')
    # ps3.savefig()
    # print('scales = np.array(', scales, ')')
    # print('dx = np.array(', dxlist, ')')
    # print('dy = np.array(', dylist, ')')
    # 
    # return
        
    
    scale = 8
    sh,sw = ph*scale, pw*scale
    subpsfim = np.zeros((sh,sw))
    step = 1./float(scale)
    for ix in np.arange(scale):
        for iy in np.arange(scale):
            dx = ix * step
            dy = iy * step
            #dx = 0.5 + (ix - 0.5) * step
            #dy = 0.5 + (iy - 0.5) * step
            #if ix == 0 and iy == 0:
            #    subpsfim[0::scale, 0::scale] = psfim
            #    continue
            shift = lanczos_shift_image(psfim, -dx, -dy, order=5)
            subpsfim[iy::scale, ix::scale] = shift

    # HACK -clamp edges to zero to counter possible weird lanczos edge issues?
    subpsfim[:2,:] = 0
    subpsfim[:,:2] = 0
    subpsfim[-2:,:] = 0
    subpsfim[:,-2:] = 0
            
    plt.clf()
    plt.subplot(1,2,1)
    dimshow(psfim)
    plt.subplot(1,2,2)
    dimshow(subpsfim)
    ps3.savefig()

    print('SubPSF image:', subpsfim.shape)
    subpixpsf = PixelizedPSF(subpsfim[:-1,:-1])
    SP,(px0,py0),(spH,spW),(sw,sv) = subpixpsf.getFourierTransform(
        0., 0., scale*halfsize)

    print('SP shape', SP.shape)
    
    wcs = NullWCS()
    wcs.pixscale /= scale
    print('subsampling image: set pixscale', wcs.pixscale)
    print('WCS:', wcs)
    
    subdata=np.zeros((scale*H,scale*W), np.float32)
    subimg = Image(data=subdata, invvar=np.ones_like(subdata), psf=tinypsf,
                   wcs=wcs)

    # Move galaxy to center of image.
    gal.pos.x = scale*pH/2.
    gal.pos.y = scale*pW/2.
    
    subtinyp = gal.getModelPatch(subimg)
    subtinypad = np.zeros((scale*pH,scale*pW))
    subtinyp.addTo(subtinypad)
    # Rotated to be zero-centered.
    subtinypad2 = np.fft.fftshift(subtinypad)
    
    plt.clf()
    dimshow(subtinypad2, **ima)
    plt.title('subtinypad2')
    ps3.savefig()

    plt.clf()
    dimshow(tinypad2, **ima)
    plt.title('tinypad2')
    ps3.savefig()
    
    Fsub = np.fft.rfft2(subtinypad2)
    tH,tW = subtinypad.shape
    Fsub /= (tH * np.pi)
    Fsub *= scale

    fima2 = fima.copy()
    fima2.update(vmin=0, vmax=1.1)

    Fsub_orig = Fsub.copy()

    # Trim Fsub to same size (63,33) vs (64,33)
    #h1,w1 = Fsub.shape
    #hm2,wm2 = Fmine2.shape
    #Fsub = Fsub[:hm2,:]
    
    plt.clf()
    dimshow(np.fft.fftshift(np.hypot(Fsub.real, Fsub.imag), axes=(0,)), **fima2)
    plt.colorbar()
    plt.title('Fsub')
    ps3.savefig()

    print('Fsub sum:', np.hypot(Fsub.real, Fsub.imag).sum())
    print('Fsub Real range:', Fsub.real.min(), Fsub.real.max())
    print('Fsub Imag range:', Fsub.imag.min(), Fsub.imag.max())

    pH,pW = subtinypad2.shape
    wt = np.fft.rfftfreq(pW)
    vt = np.fft.fftfreq(pH)
    # print('wsub:', len(wt), 'min/max', wt.min(), wt.max())
    # print('vsub:', len(vt), 'min/max', vt.min(), vt.max())

    df = np.abs(w[1] - w[0])
    w2b = np.arange(scale * (len(w)-1) + 1) * df + scale*np.min(w)
    v2b = np.arange(scale*len(v)) * df + scale*np.min(v)
    # print('w2:', w2)
    # print('w2b:', w2b)
    # print('v2:', v2)
    # print('v2b:', v2b)
    Fmine2b = amix.getFourierTransform(w2b, v2b)
    # -> shape len(v2b),len(w2b)
    
    print('Fmine2b shape', Fmine2b.shape)
    print('Fmine2b sum:', np.hypot(Fmine2b.real, Fmine2b.imag).sum())
    print('Fmine2b Real range:', Fmine2b.real.min(), Fmine2b.real.max())
    print('Fmine2b Imag range:', Fmine2b.imag.min(), Fmine2b.imag.max())

    print('Fsub_orig shape:', Fsub_orig.shape)
    
    # # My method, Fourier transform with twice the frequency range
    # plt.clf()
    # dimshow(np.hypot(Fmine2.real, Fmine2.imag), **fima2)
    # plt.colorbar()
    # plt.title('Fmine2')
    # ps3.savefig()
    # 
    # diff = np.fft.fftshift(Fsub, axes=(0,)) - Fmine2
    # print('diff Real range:', diff.real.min(), diff.real.max())
    # print('diff Imag range:', diff.imag.min(), diff.imag.max())
    # 
    # plt.clf()
    # dimshow(np.hypot(diff.real, diff.imag), **fima)
    # plt.colorbar()
    # plt.title('Fsub - Fmine2')
    # ps3.savefig()

    diff2 = np.fft.fftshift(Fsub_orig, axes=(0,)) - Fmine2b
    print('diff2 Real range:', diff.real.min(), diff.real.max())
    print('diff2 Imag range:', diff.imag.min(), diff.imag.max())
    
    plt.clf()
    dimshow(np.hypot(diff2.real, diff2.imag), **fima)
    plt.colorbar()
    plt.title('Fsub - Fmine2b')
    ps3.savefig()

    plt.clf()
    dimshow(diff2.real, **rima)
    plt.colorbar()
    plt.title('real(Fsub - Fmine2b)')
    ps3.savefig()

    print('Ftiny:', Ftiny.shape)
    print('P:', P.shape)
    print('Fsub:', Fsub.shape)
    print('SP:', SP.shape)
    print('Fmine2b:', Fmine2b.shape)
    
    #sz1 = 32
    #sz = 64
    sz1 = 32
    sz = scale * 32
    
    plt.clf()
    plt.subplot(2,2,1)
    dimshow(Ftiny.real, **rima)
    plt.colorbar()
    plt.subplot(2,2,2)
    dimshow(Ftiny.imag, **iima)
    plt.colorbar()
    plt.subplot(2,2,3)
    dimshow(P.real, **rima)
    plt.colorbar()
    plt.subplot(2,2,4)
    dimshow(P.imag, **iima)
    plt.colorbar()
    plt.suptitle('Ftiny, P')
    ps3.savefig()
    
    PG = np.fft.irfft2(Ftiny * P, s=(sz1,sz1))
    print('PG', PG.dtype, PG.shape)
    plt.clf()
    dimshow(PG, **ima)
    plt.colorbar()
    plt.title('PG')
    ps3.savefig()
    
    #P,(px0,py0),(pH,pW),(w,v) = pixpsf.getFourierTransform(0., 0., halfsize)
    #Fmine = amix.getFourierTransform(w, v)

    plt.clf()
    plt.subplot(2,2,1)
    dimshow(Fmine.real, **rima)
    plt.colorbar()
    plt.subplot(2,2,2)
    dimshow(Fmine.imag, **iima)
    plt.colorbar()
    plt.subplot(2,2,3)
    dimshow(P.real, **rima)
    plt.colorbar()
    plt.subplot(2,2,4)
    dimshow(P.imag, **iima)
    plt.colorbar()
    plt.suptitle('Fmine, P')
    ps3.savefig()

    MG = np.fft.irfft2(Fmine * P, s=(sz1,sz1))
    print('MG', MG.dtype, MG.shape)
    plt.clf()
    dimshow(MG, **ima)
    plt.colorbar()
    plt.title('MG')
    ps3.savefig()

    plt.clf()
    diffshow(PG - MG, **ima)
    plt.colorbar()
    plt.title('PG - MG')
    ps3.savefig()
    
    plt.clf()
    plt.subplot(2,2,1)
    dimshow(Fsub.real, **rima)
    plt.colorbar()
    plt.subplot(2,2,2)
    dimshow(Fsub.imag, **iima)
    plt.colorbar()
    plt.subplot(2,2,3)
    dimshow(SP.real, **rima)
    plt.colorbar()
    plt.subplot(2,2,4)
    dimshow(SP.imag, **iima)
    plt.colorbar()
    plt.suptitle('Fsub, SP')
    ps3.savefig()

    SG = np.fft.irfft2(Fsub * SP, s=(sz,sz))
    print('SG', SG.dtype, SG.shape)
    plt.clf()
    dimshow(SG, **ima)
    plt.colorbar()
    plt.title('SG')
    ps3.savefig()

    Fmine2c = np.fft.fftshift(Fmine2b, axes=(0,))
    
    plt.clf()
    plt.subplot(2,2,1)
    dimshow(Fmine2c.real, **rima)
    plt.colorbar()
    plt.subplot(2,2,2)
    dimshow(Fmine2c.imag, **iima)
    plt.colorbar()
    plt.subplot(2,2,3)
    dimshow(SP.real, **rima)
    plt.colorbar()
    plt.subplot(2,2,4)
    dimshow(SP.imag, **iima)
    plt.colorbar()
    plt.suptitle('Fmine2c, SP')
    ps3.savefig()

    MG2 = np.fft.irfft2(Fmine2c * SP, s=(sz,sz))
    print('MG2', MG2.dtype, MG2.shape)
    plt.clf()
    dimshow(MG2, **ima)
    plt.colorbar()
    plt.title('MG2')
    ps3.savefig()

    plt.clf()
    diffshow(SG - MG2, **ima)
    plt.colorbar()
    plt.title('SG - MG2')
    ps3.savefig()

    # Bin the subsampled ones...
    BSG = bin_image(SG, scale)
    BSG /= (scale**2)

    print('MG:')
    x1,y1 = measure(MG)
    print('BSG:')
    x2,y2 = measure(BSG)

    shiftBSG = lanczos_shift_image(BSG, -(x2-x1), -(y2-y1), order=5)
    
    plt.clf()
    dimshow(BSG, **ima)
    plt.colorbar()
    plt.title('BSG')
    ps3.savefig()

    plt.clf()
    diffshow(BSG - MG, **ima)
    plt.colorbar()
    plt.title('BSG - MG')
    ps3.savefig()

    plt.clf()
    diffshow(shiftBSG - MG, **ima)
    plt.colorbar()
    plt.title('shiftBSG - MG')
    ps3.savefig()