def testCopyWithinFootprintOutside(self): """Copy a footprint that is larger than the image""" target = afwImage.ImageF(100, 100) target.set(0) subTarget = afwImage.ImageF( target, afwGeom.Box2I(afwGeom.Point2I(40, 40), afwGeom.Extent2I(20, 20))) source = afwImage.ImageF(10, 30) source.setXY0(45, 45) source.set(1.0) foot = afwDetect.Footprint() foot.addSpan( 50, 50, 60 ) # Oversized on the source image, right; only some pixels overlap foot.addSpan( 60, 0, 100 ) # Oversized on the source, left and right; and on sub-target image, top foot.addSpan( 99, 0, 1000 ) # Oversized on the source image, top, left and right; aiming for segfault afwDetect.copyWithinFootprintImage(foot, source, subTarget) expected = np.zeros((100, 100)) expected[50, 50:55] = 1.0 self.assertTrue(np.all(target.getArray() == expected))
def testCopyWithinFootprintImage(self): W,H = 10,10 dims = afwGeom.Extent2I(W,H) source = afwImage.ImageF(dims) dest = afwImage.ImageF(dims) sa = source.getArray() for i in range(H): for j in range(W): sa[i,j] = 100 * i + j self.foot.addSpan(4, 3, 6) self.foot.addSpan(5, 2, 4) afwDetect.copyWithinFootprintImage(self.foot, source, dest) da = dest.getArray() self.assertEqual(da[4,2], 0) self.assertEqual(da[4,3], 403) self.assertEqual(da[4,4], 404) self.assertEqual(da[4,5], 405) self.assertEqual(da[4,6], 406) self.assertEqual(da[4,7], 0) self.assertEqual(da[5,1], 0) self.assertEqual(da[5,2], 502) self.assertEqual(da[5,3], 503) self.assertEqual(da[5,4], 504) self.assertEqual(da[5,5], 0) self.assertTrue(numpy.all(da[:4,:] == 0)) self.assertTrue(numpy.all(da[6:,:] == 0))
def testCopyWithinFootprintImage(self): W, H = 10, 10 dims = afwGeom.Extent2I(W, H) source = afwImage.ImageF(dims) dest = afwImage.ImageF(dims) sa = source.getArray() for i in range(H): for j in range(W): sa[i, j] = 100 * i + j self.foot.addSpan(4, 3, 6) self.foot.addSpan(5, 2, 4) afwDetect.copyWithinFootprintImage(self.foot, source, dest) da = dest.getArray() self.assertEqual(da[4, 2], 0) self.assertEqual(da[4, 3], 403) self.assertEqual(da[4, 4], 404) self.assertEqual(da[4, 5], 405) self.assertEqual(da[4, 6], 406) self.assertEqual(da[4, 7], 0) self.assertEqual(da[5, 1], 0) self.assertEqual(da[5, 2], 502) self.assertEqual(da[5, 3], 503) self.assertEqual(da[5, 4], 504) self.assertEqual(da[5, 5], 0) self.assertTrue(np.all(da[:4, :] == 0)) self.assertTrue(np.all(da[6:, :] == 0))
def foot_to_img(foot, img=None): fimg = afwImage.ImageF(foot.getBBox()) fimg.getArray()[:, :] = np.nan if foot.isHeavy(): foot.insert(fimg) heavy = True else: if img is None: return None, False afwDet.copyWithinFootprintImage(foot, img, fimg) # ia = img.getArray() # fa = fimg.getArray() # fbb = fimg.getBBox() # fx0,fy0 = fbb.getMinX(), fbb.getMinY() # ibb = img.getBBox() # ix0,iy0 = ibb.getMinX(), ibb.getMinY() # for span in foot.getSpans(): # y,x0,x1 = span.getY(), span.getX0(), span.getX1() # # print 'Span', y, x0, x1 # # print 'img', ix0, iy0 # # print 'shape', ia[y - iy0, x0 - ix0: x1+1 - ix0].shape # # print 'fimg', fx0, fy0, # # print 'shape', fa[y - fy0, x0 - fx0: x1+1 - fx0].shape # fa[y - fy0, x0 - fx0: x1+1 - fx0] = ia[y - iy0, x0 - ix0: x1+1 - ix0] heavy = False return fimg, heavy
def makeImage(footprint): """Make an ImageF with 1 in the footprint, and 0 elsewhere""" ones = afwImage.ImageI(bbox) ones.set(1) image = afwImage.ImageI(bbox) image.set(0) afwDetect.copyWithinFootprintImage(footprint, ones, image) return image
def testCopyWithinFootprintOutside(self): """Copy a footprint that is larger than the image""" target = afwImage.ImageF(100, 100) target.set(0) subTarget = afwImage.ImageF(target, afwGeom.Box2I(afwGeom.Point2I(40, 40), afwGeom.Extent2I(20, 20))) source = afwImage.ImageF(10, 30) source.setXY0(45, 45) source.set(1.0) foot = afwDetect.Footprint() foot.addSpan(50, 50, 60) # Oversized on the source image, right; only some pixels overlap foot.addSpan(60, 0, 100) # Oversized on the source, left and right; and on sub-target image, top foot.addSpan(99, 0, 1000) # Oversized on the source image, top, left and right; aiming for segfault afwDetect.copyWithinFootprintImage(foot, source, subTarget) expected = numpy.zeros((100, 100)) expected[50,50:55] = 1.0 self.assertTrue(numpy.all(target.getArray() == expected))
def test1(self): ''' In this test, we create a test image containing two blobs, one of which is truncated by the edge of the image. We run the detection code to get realistic peaks and footprints. We then test out the different edge treatments and assert that they do what they claim. We also make plots, tests/edge*.png ''' # Create fake image... H,W = 100,100 fpbb = afwGeom.Box2I(afwGeom.Point2I(0,0), afwGeom.Point2I(W-1,H-1)) afwimg = afwImage.MaskedImageF(fpbb) imgbb = afwimg.getBBox() img = afwimg.getImage().getArray() var = afwimg.getVariance().getArray() var[:,:] = 1. blob_fwhm = 15. blob_psf = doubleGaussianPsf(201, 201, blob_fwhm, 3.*blob_fwhm, 0.03) fakepsf_fwhm = 5. S = int(np.ceil(fakepsf_fwhm * 2.)) * 2 + 1 print 'S', S fakepsf = gaussianPsf(S, S, fakepsf_fwhm) # Create and save blob images, and add to image to deblend. blobimgs = [] XY = [(50.,50.), (90.,50.)] flux = 1e6 for x,y in XY: bim = blob_psf.computeImage(afwGeom.Point2D(x, y)) bbb = bim.getBBox() bbb.clip(imgbb) bim = bim.Factory(bim, bbb) bim2 = bim.getArray() blobimg = np.zeros_like(img) blobimg[bbb.getMinY():bbb.getMaxY()+1, bbb.getMinX():bbb.getMaxX()+1] += flux * bim2 blobimgs.append(blobimg) img[bbb.getMinY():bbb.getMaxY()+1, bbb.getMinX():bbb.getMaxX()+1] += flux * bim2 # Run the detection code to get a ~ realistic footprint thresh = afwDet.createThreshold(10., 'value', True) fpSet = afwDet.FootprintSet(afwimg, thresh, 'DETECTED', 1) fps = fpSet.getFootprints() print 'found', len(fps), 'footprints' # set EDGE bit on edge pixels. margin = 5 lo = imgbb.getMin() lo.shift(afwGeom.Extent2I(margin, margin)) hi = imgbb.getMax() hi.shift(afwGeom.Extent2I(-margin, -margin)) goodbbox = afwGeom.Box2I(lo, hi) print 'Good bbox for setting EDGE pixels:', goodbbox print 'image bbox:', imgbb edgebit = afwimg.getMask().getPlaneBitMask("EDGE") print 'edgebit:', edgebit measAlg.SourceDetectionTask.setEdgeBits(afwimg, goodbbox, edgebit) if False: plt.clf() plt.imshow(afwimg.getMask().getArray(), interpolation='nearest', origin='lower') plt.colorbar() plt.title('Mask') plt.savefig('mask.png') M = afwimg.getMask().getArray() for bit in range(32): mbit = (1 << bit) if not np.any(M & mbit): continue plt.clf() plt.imshow(M & mbit, interpolation='nearest', origin='lower') plt.colorbar() plt.title('Mask bit %i (0x%x)' % (bit, mbit)) plt.savefig('mask-%02i.png' % bit) for fp in fps: print 'peaks:', len(fp.getPeaks()) for pk in fp.getPeaks(): print ' ', pk.getIx(), pk.getIy() assert(len(fps) == 1) fp = fps[0] assert(len(fp.getPeaks()) == 2) ima = dict(interpolation='nearest', origin='lower', #cmap='gray', cmap='jet', vmin=0, vmax=400) for j,(tt,kwa) in enumerate([ ('No edge treatment', dict()), ('Ramp by PSF', dict(rampFluxAtEdge=True)), ('No clip at edge', dict(patchEdges=True)), ]): #print 'Deblending...' deb = deblend(fp, afwimg, fakepsf, fakepsf_fwhm, verbose=True, **kwa) #print 'Result:', deb #print len(deb.peaks), 'deblended peaks' parent_img = afwImage.ImageF(fpbb) afwDet.copyWithinFootprintImage(fp, afwimg.getImage(), parent_img) X = [x for x,y in XY] Y = [y for x,y in XY] PX = [pk.getIx() for pk in fp.getPeaks()] PY = [pk.getIy() for pk in fp.getPeaks()] # Grab 1-d slices to make assertion about. symms = [] monos = [] symm1ds = [] mono1ds = [] yslice = H/2 parent1d = img[yslice, :] for i,dpk in enumerate(deb.peaks): symm = dpk.origTemplate symms.append(symm) bbox = symm.getBBox() x0,y0 = bbox.getMinX(), bbox.getMinY() im = symm.getArray() h,w = im.shape oned = np.zeros(W) oned[x0: x0+w] = im[yslice-y0, :] symm1ds.append(oned) mono = afwImage.ImageF(fpbb) afwDet.copyWithinFootprintImage(dpk.templateFootprint, dpk.templateImage, mono) monos.append(mono) im = mono.getArray() bbox = mono.getBBox() x0,y0 = bbox.getMinX(), bbox.getMinY() h,w = im.shape oned = np.zeros(W) oned[x0: x0+w] = im[yslice-y0, :] mono1ds.append(oned) for i,(symm,mono) in enumerate(zip(symm1ds, mono1ds)): # for the first two cases, the basic symmetric # template for the second source drops to zero at < # ~75 where the symmetric part is outside the # footprint. if i == 1 and j in [0,1]: self.assertTrue(np.all(symm[:74] == 0)) if i == 1 and j == 2: # For the third case, the 'symm' template gets # "patched" with the parent's value self.assertTrue(np.all((symm == parent1d)[:74])) if i == 1 and j == 0: # No edge handling: mono template == 0 self.assertTrue(np.all(mono[:74] == 0)) if i == 1 and j == 1: # ramp by psf: zero up to ~65, ramps up self.assertTrue(np.all(mono[:64] == 0)) self.assertTrue(np.any(mono[65:74] > 0)) self.assertTrue(np.all(np.diff(mono)[60:80] >= 0.)) if i == 1 and j == 2: # no edge clipping: profile is monotonic and positive. self.assertTrue(np.all(np.diff(mono)[:85] >= 0.)) self.assertTrue(np.all(mono[:85] > 0.)) if not doPlot: continue plt.clf() p1 = plt.plot(parent1d, 'b-', lw=3, alpha=0.5) for i,(symm,mono) in enumerate(zip(symm1ds, mono1ds)): p2 = plt.plot(symm, 'r-', lw=2, alpha=0.7) p3 = plt.plot(mono, 'g-') plt.legend((p1[0],p2[0],p3[0]), ('Parent','Symm template', 'Mono template'), loc='upper left') plt.title('1-d slice: %s' % tt) fn = plotpat % (2*j+0) plt.savefig(fn) print 'Wrote', fn def myimshow(*args, **kwargs): x0,x1,y0,y1 = imExt(afwimg) plt.fill([x0,x0,x1,x1,x0],[y0,y1,y1,y0,y0], color=(1,1,0.8), zorder=20) plt.imshow(*args, zorder=25, **kwargs) plt.xticks([]); plt.yticks([]) plt.axis(imExt(afwimg)) plt.clf() pa = dict(color='m', marker='.', linestyle='None', zorder=30) R,C = 3,6 plt.subplot(R, C, (2*C) + 1) myimshow(img, **ima) ax = plt.axis() plt.plot(X, Y, **pa) plt.axis(ax) plt.title('Image') plt.subplot(R, C, (2*C) + 2) myimshow(parent_img.getArray(), **ima) ax = plt.axis() plt.plot(PX, PY, **pa) plt.axis(ax) plt.title('Footprint') sumimg = None for i,dpk in enumerate(deb.peaks): plt.subplot(R, C, i*C + 1) myimshow(blobimgs[i], **ima) ax = plt.axis() plt.plot(PX[i], PY[i], **pa) plt.axis(ax) plt.title('true') plt.subplot(R, C, i*C + 2) t = dpk.origTemplate myimshow(t.getArray(), extent=imExt(t), **ima) ax = plt.axis() plt.plot(PX[i], PY[i], **pa) plt.axis(ax) plt.title('symm') # monotonic template mimg = afwImage.ImageF(fpbb) afwDet.copyWithinFootprintImage(dpk.templateFootprint, dpk.templateImage, mimg) plt.subplot(R, C, i*C + 3) myimshow(mimg.getArray(), extent=imExt(mimg), **ima) ax = plt.axis() plt.plot(PX[i], PY[i], **pa) plt.axis(ax) plt.title('monotonic') plt.subplot(R, C, i*C + 4) port = dpk.fluxPortion.getImage() myimshow(port.getArray(), extent=imExt(port), **ima) plt.title('portion') ax = plt.axis() plt.plot(PX[i], PY[i], **pa) plt.axis(ax) if dpk.strayFlux is not None: simg = afwImage.ImageF(fpbb) dpk.strayFlux.insert(simg) plt.subplot(R, C, i*C + 5) myimshow(simg.getArray(), **ima) plt.title('stray') ax = plt.axis() plt.plot(PX, PY, **pa) plt.axis(ax) himg2 = afwImage.ImageF(fpbb) portion = dpk.getFluxPortion() portion.insert(himg2) if sumimg is None: sumimg = himg2.getArray().copy() else: sumimg += himg2.getArray() plt.subplot(R, C, i*C + 6) myimshow(himg2.getArray(), **ima) plt.title('portion+stray') ax = plt.axis() plt.plot(PX, PY, **pa) plt.axis(ax) plt.subplot(R, C, (2*C) + C) myimshow(sumimg, **ima) ax = plt.axis() plt.plot(X, Y, **pa) plt.axis(ax) plt.title('Sum of deblends') plt.suptitle(tt) fn = plotpat % (2*j + 1) plt.savefig(fn) print 'Wrote', fn
def test1(self): ''' In this test, we create a test image containing two blobs, one of which is truncated by the edge of the image. We run the detection code to get realistic peaks and footprints. We then test out the different edge treatments and assert that they do what they claim. We also make plots, tests/edge*.png ''' # Create fake image... H, W = 100, 100 fpbb = geom.Box2I(geom.Point2I(0, 0), geom.Point2I(W-1, H-1)) afwimg = afwImage.MaskedImageF(fpbb) imgbb = afwimg.getBBox() img = afwimg.getImage().getArray() var = afwimg.getVariance().getArray() var[:, :] = 1. blob_fwhm = 15. blob_psf = doubleGaussianPsf(201, 201, blob_fwhm, 3.*blob_fwhm, 0.03) fakepsf_fwhm = 5. S = int(np.ceil(fakepsf_fwhm * 2.)) * 2 + 1 print('S', S) fakepsf = gaussianPsf(S, S, fakepsf_fwhm) # Create and save blob images, and add to image to deblend. blobimgs = [] XY = [(50., 50.), (90., 50.)] flux = 1e6 for x, y in XY: bim = blob_psf.computeImage(geom.Point2D(x, y)) bbb = bim.getBBox() bbb.clip(imgbb) bim = bim.Factory(bim, bbb) bim2 = bim.getArray() blobimg = np.zeros_like(img) blobimg[bbb.getMinY():bbb.getMaxY()+1, bbb.getMinX():bbb.getMaxX()+1] += flux * bim2 blobimgs.append(blobimg) img[bbb.getMinY():bbb.getMaxY()+1, bbb.getMinX():bbb.getMaxX()+1] += flux * bim2 # Run the detection code to get a ~ realistic footprint thresh = afwDet.createThreshold(10., 'value', True) fpSet = afwDet.FootprintSet(afwimg, thresh, 'DETECTED', 1) fps = fpSet.getFootprints() print('found', len(fps), 'footprints') # set EDGE bit on edge pixels. margin = 5 lo = imgbb.getMin() lo.shift(geom.Extent2I(margin, margin)) hi = imgbb.getMax() hi.shift(geom.Extent2I(-margin, -margin)) goodbbox = geom.Box2I(lo, hi) print('Good bbox for setting EDGE pixels:', goodbbox) print('image bbox:', imgbb) edgebit = afwimg.getMask().getPlaneBitMask("EDGE") print('edgebit:', edgebit) measAlg.SourceDetectionTask.setEdgeBits(afwimg, goodbbox, edgebit) if False: plt.clf() plt.imshow(afwimg.getMask().getArray(), interpolation='nearest', origin='lower') plt.colorbar() plt.title('Mask') plt.savefig('mask.png') M = afwimg.getMask().getArray() for bit in range(32): mbit = (1 << bit) if not np.any(M & mbit): continue plt.clf() plt.imshow(M & mbit, interpolation='nearest', origin='lower') plt.colorbar() plt.title('Mask bit %i (0x%x)' % (bit, mbit)) plt.savefig('mask-%02i.png' % bit) for fp in fps: print('peaks:', len(fp.getPeaks())) for pk in fp.getPeaks(): print(' ', pk.getIx(), pk.getIy()) assert(len(fps) == 1) fp = fps[0] assert(len(fp.getPeaks()) == 2) ima = dict(interpolation='nearest', origin='lower', # cmap='gray', cmap='jet', vmin=0, vmax=400) for j, (tt, kwa) in enumerate([ ('No edge treatment', dict()), ('Ramp by PSF', dict(rampFluxAtEdge=True)), ('No clip at edge', dict(patchEdges=True)), ]): # print 'Deblending...' # Change verbose to False to quiet down the meas_deblender.baseline logger deb = deblend(fp, afwimg, fakepsf, fakepsf_fwhm, verbose=True, **kwa) # print 'Result:', deb # print len(deb.peaks), 'deblended peaks' parent_img = afwImage.ImageF(fpbb) fp.spans.copyImage(afwimg.getImage(), parent_img) X = [x for x, y in XY] Y = [y for x, y in XY] PX = [pk.getIx() for pk in fp.getPeaks()] PY = [pk.getIy() for pk in fp.getPeaks()] # Grab 1-d slices to make assertion about. symms = [] monos = [] symm1ds = [] mono1ds = [] yslice = H//2 parent1d = img[yslice, :] for i, dpk in enumerate(deb.deblendedParents[0].peaks): symm = dpk.origTemplate symms.append(symm) bbox = symm.getBBox() x0, y0 = bbox.getMinX(), bbox.getMinY() im = symm.getArray() h, w = im.shape oned = np.zeros(W) oned[x0: x0+w] = im[yslice-y0, :] symm1ds.append(oned) mono = afwImage.ImageF(fpbb) dpk.templateFootprint.spans.copyImage(dpk.templateImage, mono) monos.append(mono) im = mono.getArray() bbox = mono.getBBox() x0, y0 = bbox.getMinX(), bbox.getMinY() h, w = im.shape oned = np.zeros(W) oned[x0: x0+w] = im[yslice-y0, :] mono1ds.append(oned) for i, (symm, mono) in enumerate(zip(symm1ds, mono1ds)): # for the first two cases, the basic symmetric # template for the second source drops to zero at < # ~75 where the symmetric part is outside the # footprint. if i == 1 and j in [0, 1]: self.assertFloatsEqual(symm[:74], 0.0) if i == 1 and j == 2: # For the third case, the 'symm' template gets # "patched" with the parent's value self.assertFloatsEqual(symm[:74], parent1d[:74]) if i == 1 and j == 0: # No edge handling: mono template == 0 self.assertFloatsEqual(mono[:74], 0.0) if i == 1 and j == 1: # ramp by psf: zero up to ~65, ramps up self.assertFloatsEqual(mono[:64], 0.0) self.assertTrue(np.any(mono[65:74] > 0)) self.assertTrue(np.all(np.diff(mono)[60:80] >= 0.)) if i == 1 and j == 2: # no edge clipping: profile is monotonic and positive. self.assertTrue(np.all(np.diff(mono)[:85] >= 0.)) self.assertTrue(np.all(mono[:85] > 0.)) if not doPlot: continue plt.clf() p1 = plt.plot(parent1d, 'b-', lw=3, alpha=0.5) for i, (symm, mono) in enumerate(zip(symm1ds, mono1ds)): p2 = plt.plot(symm, 'r-', lw=2, alpha=0.7) p3 = plt.plot(mono, 'g-') plt.legend((p1[0], p2[0], p3[0]), ('Parent', 'Symm template', 'Mono template'), loc='upper left') plt.title('1-d slice: %s' % tt) fn = plotpat % (2*j+0) plt.savefig(fn) print('Wrote', fn) def myimshow(*args, **kwargs): x0, x1, y0, y1 = imExt(afwimg) plt.fill([x0, x0, x1, x1, x0], [y0, y1, y1, y0, y0], color=(1, 1, 0.8), zorder=20) plt.imshow(*args, zorder=25, **kwargs) plt.xticks([]) plt.yticks([]) plt.axis(imExt(afwimg)) plt.clf() pa = dict(color='m', marker='.', linestyle='None', zorder=30) R, C = 3, 6 plt.subplot(R, C, (2*C) + 1) myimshow(img, **ima) ax = plt.axis() plt.plot(X, Y, **pa) plt.axis(ax) plt.title('Image') plt.subplot(R, C, (2*C) + 2) myimshow(parent_img.getArray(), **ima) ax = plt.axis() plt.plot(PX, PY, **pa) plt.axis(ax) plt.title('Footprint') sumimg = None for i, dpk in enumerate(deb.deblendedParents[0].peaks): plt.subplot(R, C, i*C + 1) myimshow(blobimgs[i], **ima) ax = plt.axis() plt.plot(PX[i], PY[i], **pa) plt.axis(ax) plt.title('true') plt.subplot(R, C, i*C + 2) t = dpk.origTemplate myimshow(t.getArray(), extent=imExt(t), **ima) ax = plt.axis() plt.plot(PX[i], PY[i], **pa) plt.axis(ax) plt.title('symm') # monotonic template mimg = afwImage.ImageF(fpbb) afwDet.copyWithinFootprintImage(dpk.templateFootprint, dpk.templateImage, mimg) plt.subplot(R, C, i*C + 3) myimshow(mimg.getArray(), extent=imExt(mimg), **ima) ax = plt.axis() plt.plot(PX[i], PY[i], **pa) plt.axis(ax) plt.title('monotonic') plt.subplot(R, C, i*C + 4) port = dpk.fluxPortion.getImage() myimshow(port.getArray(), extent=imExt(port), **ima) plt.title('portion') ax = plt.axis() plt.plot(PX[i], PY[i], **pa) plt.axis(ax) if dpk.strayFlux is not None: simg = afwImage.ImageF(fpbb) dpk.strayFlux.insert(simg) plt.subplot(R, C, i*C + 5) myimshow(simg.getArray(), **ima) plt.title('stray') ax = plt.axis() plt.plot(PX, PY, **pa) plt.axis(ax) himg2 = afwImage.ImageF(fpbb) portion = dpk.getFluxPortion() portion.insert(himg2) if sumimg is None: sumimg = himg2.getArray().copy() else: sumimg += himg2.getArray() plt.subplot(R, C, i*C + 6) myimshow(himg2.getArray(), **ima) plt.title('portion+stray') ax = plt.axis() plt.plot(PX, PY, **pa) plt.axis(ax) plt.subplot(R, C, (2*C) + C) myimshow(sumimg, **ima) ax = plt.axis() plt.plot(X, Y, **pa) plt.axis(ax) plt.title('Sum of deblends') plt.suptitle(tt) fn = plotpat % (2*j + 1) plt.savefig(fn) print('Wrote', fn)
def test1(self): ''' A simple example: three overlapping blobs (detected as 1 footprint with three peaks). We artificially omit one of the peaks, meaning that its flux is "stray". Assert that the stray flux assigned to the other two peaks accounts for all the flux in the parent. ''' H,W = 100,100 fpbb = afwGeom.Box2I(afwGeom.Point2I(0,0), afwGeom.Point2I(W-1,H-1)) afwimg = afwImage.MaskedImageF(fpbb) imgbb = afwimg.getBBox(afwImage.PARENT) img = afwimg.getImage().getArray() var = afwimg.getVariance().getArray() var[:,:] = 1. blob_fwhm = 10. blob_psf = doubleGaussianPsf(99, 99, blob_fwhm, 3.*blob_fwhm, 0.03) fakepsf_fwhm = 3. fakepsf = gaussianPsf(11, 11, fakepsf_fwhm) blobimgs = [] x = 75. XY = [(x,35.), (x,65.), (50.,50.)] flux = 1e6 for x,y in XY: bim = blob_psf.computeImage(afwGeom.Point2D(x, y)) bbb = bim.getBBox(afwImage.PARENT) bbb.clip(imgbb) bim = bim.Factory(bim, bbb, afwImage.PARENT) bim2 = bim.getArray() blobimg = np.zeros_like(img) blobimg[bbb.getMinY():bbb.getMaxY()+1, bbb.getMinX():bbb.getMaxX()+1] += flux * bim2 blobimgs.append(blobimg) img[bbb.getMinY():bbb.getMaxY()+1, bbb.getMinX():bbb.getMaxX()+1] += flux * bim2 # Run the detection code to get a ~ realistic footprint thresh = afwDet.createThreshold(5., 'value', True) fpSet = afwDet.FootprintSet(afwimg, thresh, 'DETECTED', 1) fps = fpSet.getFootprints() print 'found', len(fps), 'footprints' pks2 = [] for fp in fps: print 'peaks:', len(fp.getPeaks()) for pk in fp.getPeaks(): print ' ', pk.getIx(), pk.getIy() pks2.append((pk.getIx(), pk.getIy())) # The first peak in this list is the one we want to omit. fp0 = fps[0] fakefp = afwDet.Footprint(fp0.getSpans(), fp0.getBBox()) for pk in fp0.getPeaks()[1:]: fakefp.getPeaks().append(pk) ima = dict(interpolation='nearest', origin='lower', cmap='gray', vmin=0, vmax=1e3) if doPlot: plt.figure(figsize=(12,6)) plt.clf() plt.suptitle('strayFlux.py: test1 input') plt.subplot(2,2,1) plt.title('Image') plt.imshow(img, **ima) ax = plt.axis() plt.plot([x for x,y in XY], [y for x,y in XY], 'r.') plt.axis(ax) for i,(b,(x,y)) in enumerate(zip(blobimgs, XY)): plt.subplot(2,2, 2+i) plt.title('Blob %i' % i) plt.imshow(b, **ima) ax = plt.axis() plt.plot(x, y, 'r.') plt.axis(ax) plt.savefig(plotpat % 1) deb = deblend(fakefp, afwimg, fakepsf, fakepsf_fwhm, verbose=True) parent_img = afwImage.ImageF(fpbb) afwDet.copyWithinFootprintImage(fakefp, afwimg.getImage(), parent_img) if doPlot: def myimshow(*args, **kwargs): plt.imshow(*args, **kwargs) plt.xticks([]); plt.yticks([]) plt.axis(imExt(afwimg)) plt.clf() plt.suptitle('strayFlux.py: test1 results') #R,C = 3,5 R,C = 3,4 plt.subplot(R, C, (2*C) + 1) plt.title('Image') myimshow(img, **ima) ax = plt.axis() plt.plot([x for x,y in XY], [y for x,y in XY], 'r.') plt.axis(ax) plt.subplot(R, C, (2*C) + 2) plt.title('Parent footprint') myimshow(parent_img.getArray(), **ima) ax = plt.axis() plt.plot([pk.getIx() for pk in fakefp.getPeaks()], [pk.getIy() for pk in fakefp.getPeaks()], 'r.') plt.axis(ax) sumimg = None for i,dpk in enumerate(deb.peaks): plt.subplot(R, C, i*C + 1) plt.title('ch%i symm' % i) symm = dpk.templateImage myimshow(symm.getArray(), extent=imExt(symm), **ima) plt.subplot(R, C, i*C + 2) plt.title('ch%i portion' % i) port = dpk.fluxPortion.getImage() myimshow(port.getArray(), extent=imExt(port), **ima) himg = afwImage.ImageF(fpbb) heavy = dpk.getFluxPortion(strayFlux=False) heavy.insert(himg) # plt.subplot(R, C, i*C + 3) # plt.title('ch%i heavy' % i) # myimshow(himg.getArray(), **ima) # ax = plt.axis() # plt.plot([x for x,y in XY], [y for x,y in XY], 'r.') # plt.axis(ax) simg = afwImage.ImageF(fpbb) dpk.strayFlux.insert(simg) plt.subplot(R, C, i*C + 3) plt.title('ch%i stray' % i) myimshow(simg.getArray(), **ima) ax = plt.axis() plt.plot([x for x,y in XY], [y for x,y in XY], 'r.') plt.axis(ax) himg2 = afwImage.ImageF(fpbb) heavy = dpk.getFluxPortion(strayFlux=True) heavy.insert(himg2) if sumimg is None: sumimg = himg2.getArray().copy() else: sumimg += himg2.getArray() plt.subplot(R, C, i*C + 4) myimshow(himg2.getArray(), **ima) plt.title('ch%i total' % i) ax = plt.axis() plt.plot([x for x,y in XY], [y for x,y in XY], 'r.') plt.axis(ax) plt.subplot(R, C, (2*C) + C) myimshow(sumimg, **ima) ax = plt.axis() plt.plot([x for x,y in XY], [y for x,y in XY], 'r.') plt.axis(ax) plt.title('Sum of deblends') plt.savefig(plotpat % 2) # Compute the sum-of-children image sumimg = None for i,dpk in enumerate(deb.peaks): himg2 = afwImage.ImageF(fpbb) dpk.getFluxPortion().insert(himg2) if sumimg is None: sumimg = himg2.getArray().copy() else: sumimg += himg2.getArray() # Sum of children ~= Original image inside footprint (parent_img) absdiff = np.max(np.abs(sumimg - parent_img.getArray())) print 'Max abs diff:', absdiff imgmax = parent_img.getArray().max() print 'Img max:', imgmax self.assertTrue(absdiff < imgmax * 1e-6)