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()
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()
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?
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()
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?
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()