def testDot(self): """Test HeavyFootprint::dot""" size = 20, 20 for xOffset, yOffset in [(0, 0), (0, 3), (3, 0), (2, 2)]: mi1 = afwImage.MaskedImageF(*size) mi2 = afwImage.MaskedImageF(*size) mi1.set(0) mi2.set(0) spanList1 = [] spanList2 = [] for y, x0, x1 in [ (5, 3, 7), (6, 3, 4), (6, 6, 7), (7, 3, 7), ]: spanList1.append(afwGeom.Span(y, x0, x1)) spanList2.append( afwGeom.Span(y + yOffset, x0 + xOffset, x1 + xOffset)) for x in range(x0, x1 + 1): value = (x + y, 0, 1.0) mi1[x, y, afwImage.LOCAL] = value mi2[x + xOffset, y + yOffset, afwImage.LOCAL] = value fp1 = afwDetect.Footprint(afwGeom.SpanSet(spanList1)) fp2 = afwDetect.Footprint(afwGeom.SpanSet(spanList2)) hfp1 = afwDetect.makeHeavyFootprint(fp1, mi1) hfp2 = afwDetect.makeHeavyFootprint(fp2, mi2) dot = np.vdot(mi1.getImage().getArray(), mi2.getImage().getArray()) self.assertEqual(hfp1.dot(hfp2), dot) self.assertEqual(hfp2.dot(hfp1), dot)
def testSplit(self): spanList = [ afwGeom.Span(0, 2, 4), afwGeom.Span(1, 2, 4), afwGeom.Span(2, 2, 4), afwGeom.Span(10, 4, 7), afwGeom.Span(11, 4, 7), afwGeom.Span(12, 4, 7) ] spans = afwGeom.SpanSet(spanList) region = lsst.geom.Box2I(lsst.geom.PointI(-6, -6), lsst.geom.PointI(20, 20)) multiFoot = afwDet.Footprint(spans, region) records = [multiFoot.addPeak(3, 1, 100), multiFoot.addPeak(5, 11, 100)] # Verify that the footprint is multi-component self.assertFalse(multiFoot.isContiguous()) footprintList = multiFoot.split() self.assertEqual(len(footprintList), 2) for i, fp in enumerate(footprintList): # check that the correct Spans are populated for each tempSpan = afwGeom.SpanSet(spanList[i * 3:i * 3 + 3]) self.assertEqual(fp.spans, tempSpan) # check that the peaks are split properly self.assertEqual(len(fp.peaks), 1) self.assertEqual(fp.peaks[0], records[i])
def testIsContiguous(self): spanSetConList = [afwGeom.Span(0, 2, 5), afwGeom.Span(1, 5, 8)] spanSetCon = afwGeom.SpanSet(spanSetConList) self.assertTrue(spanSetCon.isContiguous()) spanSetNotConList = [afwGeom.Span(0, 2, 5), afwGeom.Span(1, 20, 25)] spanSetNotCon = afwGeom.SpanSet(spanSetNotConList) self.assertFalse(spanSetNotCon.isContiguous())
def testMergeFootprints(self): f1 = self.foot f2 = afwDetect.Footprint() spanList1 = [(10, 10, 20), (10, 30, 40), (10, 50, 60), (11, 30, 50), (12, 30, 50), (13, 10, 20), (13, 30, 40), (13, 50, 60), (15, 10, 20), (15, 31, 40), (15, 51, 60)] spanSet1 = afwGeom.SpanSet([afwGeom.Span(*span) for span in spanList1]) f1.spans = spanSet1 spanList2 = [(8, 10, 20), (9, 20, 30), (10, 0, 9), (10, 35, 65), (10, 70, 80), (13, 49, 54), (14, 10, 30), (15, 21, 30), (15, 41, 50), (15, 61, 70)] spanSet2 = afwGeom.SpanSet([afwGeom.Span(*span) for span in spanList2]) f2.spans = spanSet2 fA = afwDetect.mergeFootprints(f1, f2) fB = afwDetect.mergeFootprints(f2, f1) ims = [] for i, f in enumerate([f1, f2, fA, fB]): im1 = afwImage.ImageU(100, 100) im1.set(0) imbb = im1.getBBox() f.setRegion(imbb) f.spans.setImage(im1, 1) ims.append(im1) for i, merged in enumerate([ims[2], ims[3]]): m = merged.getArray() a1 = ims[0].getArray() a2 = ims[1].getArray() # Slightly looser tests to start... # Every pixel in f1 is in f[AB] self.assertTrue(np.all(m.flat[np.flatnonzero(a1)] == 1)) # Every pixel in f2 is in f[AB] self.assertTrue(np.all(m.flat[np.flatnonzero(a2)] == 1)) # merged == a1 | a2. self.assertTrue(np.all(m == np.maximum(a1, a2))) if False: import matplotlib matplotlib.use('Agg') import pylab as plt plt.clf() for i, im1 in enumerate(ims): plt.subplot(4, 1, i + 1) plt.imshow(im1.getArray(), interpolation='nearest', origin='lower') plt.axis([0, 100, 0, 20]) plt.savefig('merge2.png')
def testIteratorConstructor(self): spans = [afwGeom.Span(0, 2, 4), afwGeom.Span(1, 2, 4), afwGeom.Span(2, 2, 4)] spanSetFromList = afwGeom.SpanSet(spans) spanSetFromArray = afwGeom.SpanSet(np.array(spans)) self.assertEqual(spanSetFromList.getBBox().getMinX(), 2) self.assertEqual(spanSetFromList.getBBox().getMaxX(), 4) self.assertEqual(spanSetFromList.getBBox().getMinY(), 0) self.assertEqual(spanSetFromArray.getBBox().getMinX(), 2) self.assertEqual(spanSetFromArray.getBBox().getMaxX(), 4) self.assertEqual(spanSetFromArray.getBBox().getMinY(), 0)
def testInclude(self): """Test that we can expand a Footprint to include the union of itself and all others provided.""" region = lsst.geom.Box2I(lsst.geom.Point2I(-6, -6), lsst.geom.Point2I(6, 6)) parentSpanSet = afwGeom.SpanSet( lsst.geom.Box2I(lsst.geom.Point2I(-2, -2), lsst.geom.Point2I(2, 2))) parent = afwDetect.Footprint(parentSpanSet, region) parent.addPeak(0, 0, float("NaN")) child1SpanSet = afwGeom.SpanSet( lsst.geom.Box2I(lsst.geom.Point2I(-3, 0), lsst.geom.Point2I(0, 3))) child1 = afwDetect.Footprint(child1SpanSet, region) child1.addPeak(-1, 1, float("NaN")) child2SpanSet = afwGeom.SpanSet( lsst.geom.Box2I(lsst.geom.Point2I(-4, -3), lsst.geom.Point2I(-1, 0))) child2 = afwDetect.Footprint(child2SpanSet, region) child3SpanSet = afwGeom.SpanSet( lsst.geom.Box2I(lsst.geom.Point2I(4, -1), lsst.geom.Point2I(6, 1))) child3 = afwDetect.Footprint(child3SpanSet) merge123 = afwDetect.Footprint(parent) merge123.spans = merge123.spans.union(child1.spans).union( child2.spans).union(child3.spans) self.assertTrue(merge123.getBBox().contains(parent.getBBox())) self.assertTrue(merge123.getBBox().contains(child1.getBBox())) self.assertTrue(merge123.getBBox().contains(child2.getBBox())) self.assertTrue(merge123.getBBox().contains(child3.getBBox())) mask123a = afwImage.Mask(region) mask123b = afwImage.Mask(region) parent.spans.setMask(mask123a, 1) child1.spans.setMask(mask123a, 1) child2.spans.setMask(mask123a, 1) child3.spans.setMask(mask123a, 1) merge123.spans.setMask(mask123b, 1) self.assertEqual(mask123a.getArray().sum(), merge123.getArea()) self.assertFloatsAlmostEqual(mask123a.getArray(), mask123b.getArray(), rtol=0, atol=0) # Test that ignoreSelf=True works for include childOnly = afwDetect.Footprint() childOnly.spans = childOnly.spans.union(child1.spans).union( child2.spans).union(child3.spans) merge123 = afwDetect.Footprint(parent) merge123.spans = child1.spans.union(child2.spans).union(child3.spans) maskChildren = afwImage.Mask(region) mask123 = afwImage.Mask(region) childOnly.spans.setMask(maskChildren, 1) merge123.spans.setMask(mask123, 1) self.assertTrue(np.all(maskChildren.getArray() == mask123.getArray()))
def testCopy(self): bbox = lsst.geom.BoxI(lsst.geom.PointI(0, 2), lsst.geom.PointI(5, 6)) fp = afwDetect.Footprint(afwGeom.SpanSet(bbox), bbox) # test copy construct fp2 = afwDetect.Footprint(fp) self.assertEqual(fp2.getBBox(), bbox) self.assertEqual(fp2.getRegion(), bbox) self.assertEqual(fp2.getArea(), bbox.getArea()) y = bbox.getMinY() for s in fp2.getSpans(): self.assertEqual(s.getY(), y) self.assertEqual(s.getX0(), bbox.getMinX()) self.assertEqual(s.getX1(), bbox.getMaxX()) y += 1 # test assignment fp3 = afwDetect.Footprint() fp3.assign(fp) self.assertEqual(fp3.getBBox(), bbox) self.assertEqual(fp3.getRegion(), bbox) self.assertEqual(fp3.getArea(), bbox.getArea()) y = bbox.getMinY() for s in fp3.getSpans(): self.assertEqual(s.getY(), y) self.assertEqual(s.getX0(), bbox.getMinX()) self.assertEqual(s.getX1(), bbox.getMaxX()) y += 1
def testCopyWithinFootprintImage(self): W, H = 10, 10 dims = lsst.geom.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 footSpans = [s for s in self.foot.spans] footSpans.append(afwGeom.Span(4, 3, 6)) footSpans.append(afwGeom.Span(5, 2, 4)) self.foot.spans = afwGeom.SpanSet(footSpans) self.foot.spans.copyImage(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 testCopyWithinFootprintOutside(self): """Copy a footprint that is larger than the image""" target = afwImage.ImageF(100, 100) target.set(0) subTarget = afwImage.ImageF( target, lsst.geom.Box2I(lsst.geom.Point2I(40, 40), lsst.geom.Extent2I(20, 20))) source = afwImage.ImageF(10, 30) source.setXY0(45, 45) source.set(1.0) foot = afwDetect.Footprint() spanList = [ afwGeom.Span(*s) for s in ( ( 50, 50, 60 ), # Oversized on the source image, right; only some pixels overlap ( 60, 0, 100 ), # Oversized on the source, left and right; and on sub-target image, top ( 99, 0, 1000 ), # Oversized on the source image, top, left and right; aiming for segfault ) ] foot.spans = afwGeom.SpanSet(spanList) foot.spans.clippedTo(subTarget.getBBox()).clippedTo(source.getBBox()).\ copyImage(source, subTarget) expected = np.zeros((100, 100)) expected[50, 50:55] = 1.0 self.assertTrue(np.all(target.getArray() == expected))
def testBBoxSpanSet(self): boxSS = afwGeom.SpanSet(afwGeom.Box2I(afwGeom.Point2I(2, 2), afwGeom.Point2I(6, 6))) self.assertEqual(boxSS.getArea(), 25) bBox = boxSS.getBBox() self.assertEqual(bBox.getMinX(), 2) self.assertEqual(bBox.getMinY(), 2)
def testFindEdgePixels(self): spanSet = afwGeom.SpanSet.fromShape(6, afwGeom.Stencil.CIRCLE) spanSetEdge = spanSet.findEdgePixels() truthSpans = [afwGeom.Span(-6, 0, 0), afwGeom.Span(-5, -3, -1), afwGeom.Span(-5, 1, 3), afwGeom.Span(-4, -4, -4), afwGeom.Span(-4, 4, 4), afwGeom.Span(-3, -5, -5), afwGeom.Span(-3, 5, 5), afwGeom.Span(-2, -5, -5), afwGeom.Span(-2, 5, 5), afwGeom.Span(-1, -5, -5), afwGeom.Span(-1, 5, 5), afwGeom.Span(0, -6, -6), afwGeom.Span(0, 6, 6), afwGeom.Span(1, -5, -5), afwGeom.Span(1, 5, 5), afwGeom.Span(2, -5, -5), afwGeom.Span(2, 5, 5), afwGeom.Span(3, -5, -5), afwGeom.Span(3, 5, 5), afwGeom.Span(4, -4, -4), afwGeom.Span(4, 4, 4), afwGeom.Span(5, -3, -1), afwGeom.Span(5, 1, 3), afwGeom.Span(6, 0, 0)] truthSpanSet = afwGeom.SpanSet(truthSpans) self.assertEqual(spanSetEdge, truthSpanSet)
def testCopyWithinFootprintMaskedImage(self): W, H = 10, 10 dims = lsst.geom.Extent2I(W, H) source = afwImage.MaskedImageF(dims) dest = afwImage.MaskedImageF(dims) sa = source.getImage().getArray() sv = source.getVariance().getArray() sm = source.getMask().getArray() for i in range(H): for j in range(W): sa[i, j] = 100 * i + j sv[i, j] = 100 * j + i sm[i, j] = 1 footSpans = [s for s in self.foot.spans] footSpans.append(afwGeom.Span(4, 3, 6)) footSpans.append(afwGeom.Span(5, 2, 4)) self.foot.spans = afwGeom.SpanSet(footSpans) self.foot.spans.copyMaskedImage(source, dest) da = dest.getImage().getArray() dv = dest.getVariance().getArray() dm = dest.getMask().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)) self.assertEqual(dv[4, 2], 0) self.assertEqual(dv[4, 3], 304) self.assertEqual(dv[4, 4], 404) self.assertEqual(dv[4, 5], 504) self.assertEqual(dv[4, 6], 604) self.assertEqual(dv[4, 7], 0) self.assertEqual(dv[5, 1], 0) self.assertEqual(dv[5, 2], 205) self.assertEqual(dv[5, 3], 305) self.assertEqual(dv[5, 4], 405) self.assertEqual(dv[5, 5], 0) self.assertTrue(np.all(dv[:4, :] == 0)) self.assertTrue(np.all(dv[6:, :] == 0)) self.assertTrue(np.all(dm[4, 3:7] == 1)) self.assertTrue(np.all(dm[5, 2:5] == 1)) self.assertTrue(np.all(dm[:4, :] == 0)) self.assertTrue(np.all(dm[6:, :] == 0)) self.assertTrue(np.all(dm[4, :3] == 0)) self.assertTrue(np.all(dm[4, 7:] == 0))
def testFootprintToBBoxList(self): """Test footprintToBBoxList""" region = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(12, 10)) foot = afwDetect.Footprint(afwGeom.SpanSet(), region) spanList = [ afwGeom.Span(*span) for span in ((3, 3, 5), (3, 7, 7), (4, 2, 3), (4, 5, 7), (5, 2, 3), (5, 5, 8), (6, 3, 5)) ] foot.spans = afwGeom.SpanSet(spanList) idImage = afwImage.ImageU(region.getDimensions()) idImage.set(0) foot.spans.setImage(idImage, 1) if display: disp = afwDisplay.Display(frame=1) disp.mtv(idImage, title=self._testMethodName + " image") idImageFromBBox = idImage.Factory(idImage, True) idImageFromBBox.set(0) bboxes = afwDetect.footprintToBBoxList(foot) for bbox in bboxes: x0, y0, x1, y1 = bbox.getMinX(), bbox.getMinY(), \ bbox.getMaxX(), bbox.getMaxY() for y in range(y0, y1 + 1): for x in range(x0, x1 + 1): idImageFromBBox[x, y, afwImage.LOCAL] = 1 if display: x0 -= 0.5 y0 -= 0.5 x1 += 0.5 y1 += 0.5 disp.line([(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)], ctype=afwDisplay.RED) idImageFromBBox -= idImage # should be blank stats = afwMath.makeStatistics(idImageFromBBox, afwMath.MAX) self.assertEqual(stats.getValue(), 0)
def runMeasurement(self, algorithmName, imageid, x, y, v): """Run the measurement algorithm on an image""" # load the test image imgFile = os.path.join(self.dataDir, "image.%d.fits" % imageid) img = afwImage.ImageF(imgFile) img -= self.bkgd nx, ny = img.getWidth(), img.getHeight() msk = afwImage.Mask(geom.Extent2I(nx, ny), 0x0) var = afwImage.ImageF(geom.Extent2I(nx, ny), v) mimg = afwImage.MaskedImageF(img, msk, var) msk.getArray()[:] = np.where(np.fabs(img.getArray()) < 1.0e-8, msk.getPlaneBitMask("BAD"), 0) # Put it in a bigger image, in case it matters big = afwImage.MaskedImageF(self.offset + mimg.getDimensions()) big.getImage().set(0) big.getMask().set(0) big.getVariance().set(v) subBig = afwImage.MaskedImageF(big, geom.Box2I(big.getXY0() + self.offset, mimg.getDimensions())) subBig <<= mimg mimg = big mimg.setXY0(self.xy0) exposure = afwImage.makeExposure(mimg) cdMatrix = np.array([1.0/(2.53*3600.0), 0.0, 0.0, 1.0/(2.53*3600.0)]) cdMatrix.shape = (2, 2) exposure.setWcs(afwGeom.makeSkyWcs(crpix=geom.Point2D(1.0, 1.0), crval=geom.SpherePoint(0, 0, geom.degrees), cdMatrix=cdMatrix)) # load the corresponding test psf psfFile = os.path.join(self.dataDir, "psf.%d.fits" % imageid) psfImg = afwImage.ImageD(psfFile) psfImg -= self.bkgd kernel = afwMath.FixedKernel(psfImg) kernelPsf = algorithms.KernelPsf(kernel) exposure.setPsf(kernelPsf) # perform the shape measurement msConfig = base.SingleFrameMeasurementConfig() alg = base.SingleFramePlugin.registry[algorithmName].PluginClass.AlgClass control = base.SingleFramePlugin.registry[algorithmName].PluginClass.ConfigClass().makeControl() msConfig.algorithms.names = [algorithmName] # Note: It is essential to remove the floating point part of the position for the # Algorithm._apply. Otherwise, when the PSF is realised it will have been warped # to account for the sub-pixel offset and we won't get *exactly* this PSF. plugin, table = makePluginAndCat(alg, algorithmName, control, centroid="centroid") center = geom.Point2D(int(x), int(y)) + geom.Extent2D(self.offset + geom.Extent2I(self.xy0)) source = table.makeRecord() source.set("centroid_x", center.getX()) source.set("centroid_y", center.getY()) source.setFootprint(afwDetection.Footprint(afwGeom.SpanSet(exposure.getBBox(afwImage.PARENT)))) plugin.measure(source, exposure) return source
def setUp(self): self.mi = afwImage.MaskedImageF(20, 10) self.objectPixelVal = (10, 0x1, 100) spanList = [] for y, x0, x1 in [(2, 10, 13), (3, 11, 14)]: spanList.append(afwGeom.Span(y, x0, x1)) for x in range(x0, x1 + 1): self.mi[x, y, afwImage.LOCAL] = self.objectPixelVal self.foot = afwDetect.Footprint(afwGeom.SpanSet(spanList))
def testPeakSort(self): spanSet = afwGeom.SpanSet(lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Point2I(10, 10))) footprint = afwDetect.Footprint(spanSet) footprint.addPeak(4, 5, 1) footprint.addPeak(3, 2, 5) footprint.addPeak(7, 8, -2) footprint.addPeak(5, 7, 4) footprint.sortPeaks() self.assertEqual([peak.getIx() for peak in footprint.getPeaks()], [3, 5, 4, 7])
def testGrow(self): """Test growing a footprint""" x0, y0 = 20, 20 width, height = 20, 30 spanSet = afwGeom.SpanSet( lsst.geom.Box2I(lsst.geom.Point2I(x0, y0), lsst.geom.Extent2I(width, height))) foot1 = afwDetect.Footprint( spanSet, lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(100, 100))) # Add some peaks and check that they get copied into the new grown footprint foot1.addPeak(20, 20, 1) foot1.addPeak(30, 35, 2) foot1.addPeak(25, 45, 3) self.assertEqual(len(foot1.getPeaks()), 3) bbox1 = foot1.getBBox() self.assertEqual(bbox1.getMinX(), x0) self.assertEqual(bbox1.getMaxX(), x0 + width - 1) self.assertEqual(bbox1.getWidth(), width) self.assertEqual(bbox1.getMinY(), y0) self.assertEqual(bbox1.getMaxY(), y0 + height - 1) self.assertEqual(bbox1.getHeight(), height) ngrow = 5 for isotropic in (True, False): foot2 = afwDetect.Footprint().assign(foot1) stencil = afwGeom.Stencil.CIRCLE if isotropic else \ afwGeom.Stencil.MANHATTAN foot2.dilate(ngrow, stencil) # Check that the grown footprint is bigger than the original self.assertGreater(foot2.getArea(), foot1.getArea()) # Check that peaks got copied into grown footprint self.assertEqual(len(foot2.getPeaks()), 3) for peak in foot2.getPeaks(): self.assertIn((peak.getIx(), peak.getIy()), [(20, 20), (30, 35), (25, 45)]) bbox2 = foot2.getBBox() # check bbox2 self.assertEqual(bbox2.getMinX(), x0 - ngrow) self.assertEqual(bbox2.getWidth(), width + 2 * ngrow) self.assertEqual(bbox2.getMinY(), y0 - ngrow) self.assertEqual(bbox2.getHeight(), height + 2 * ngrow) # Check that region was preserved self.assertEqual(foot1.getRegion(), foot2.getRegion())
def testMergeFootprints(self): f1 = self.foot f2 = afwDetect.Footprint() spanList1 = [(10, 10, 20), (10, 30, 40), (10, 50, 60), (11, 30, 50), (12, 30, 50), (13, 10, 20), (13, 30, 40), (13, 50, 60), (15, 10, 20), (15, 31, 40), (15, 51, 60)] spanSet1 = afwGeom.SpanSet([afwGeom.Span(*span) for span in spanList1]) f1.spans = spanSet1 spanList2 = [(8, 10, 20), (9, 20, 30), (10, 0, 9), (10, 35, 65), (10, 70, 80), (13, 49, 54), (14, 10, 30), (15, 21, 30), (15, 41, 50), (15, 61, 70)] spanSet2 = afwGeom.SpanSet([afwGeom.Span(*span) for span in spanList2]) f2.spans = spanSet2 fA = afwDetect.mergeFootprints(f1, f2) fB = afwDetect.mergeFootprints(f2, f1) ims = [] for i, f in enumerate([f1, f2, fA, fB]): im1 = afwImage.ImageU(100, 100) im1.set(0) imbb = im1.getBBox() f.setRegion(imbb) f.spans.setImage(im1, 1) ims.append(im1) for i, merged in enumerate([ims[2], ims[3]]): m = merged.getArray() a1 = ims[0].getArray() a2 = ims[1].getArray() # Slightly looser tests to start... # Every pixel in f1 is in f[AB] self.assertTrue(np.all(m.flat[np.flatnonzero(a1)] == 1)) # Every pixel in f2 is in f[AB] self.assertTrue(np.all(m.flat[np.flatnonzero(a2)] == 1)) # merged == a1 | a2. self.assertTrue(np.all(m == np.maximum(a1, a2)))
def maskPixelsFromDefectList(maskedImage, defectList, maskName='BAD'): """Set mask plane based on a defect list @param[in,out] maskedImage afw.image.MaskedImage to process; mask plane is updated @param[in] defectList a list of defects (afw.meas.algorithms.Defect) @param[in] maskName mask plane name """ # mask bad pixels mask = maskedImage.getMask() bitmask = mask.getPlaneBitMask(maskName) for defect in defectList: bbox = defect.getBBox() afwGeom.SpanSet(bbox).clippedTo(mask.getBBox()).setMask(mask, bitmask)
def testGetBBox(self): """Check that Footprint.getBBox() returns a copy""" x0, y0, w, h = 9, 10, 7, 4 spanSet = afwGeom.SpanSet(lsst.geom.Box2I(lsst.geom.Point2I(x0, y0), lsst.geom.Extent2I(w, h))) foot = afwDetect.Footprint(spanSet) bbox = foot.getBBox() dx, dy = 10, 20 bbox.shift(lsst.geom.Extent2I(dx, dy)) self.assertEqual(bbox.getMinX(), x0 + dx) self.assertEqual(foot.getBBox().getMinX(), x0)
def testEdge(self): """Test for Footprint::findEdgePixels()""" foot = afwDetect.Footprint() spanList = [ afwGeom.Span(*span) for span in ((3, 3, 9), (4, 2, 4), (4, 6, 7), (4, 9, 11), (5, 3, 9), (6, 6, 7)) ] foot.spans = afwGeom.SpanSet(spanList) self.checkEdge(foot) # This footprint came from a very large Footprint in a deep HSC coadd patch self.checkEdge( afwDetect.Footprint.readFits( os.path.join(testPath, "testFootprintEdge.fits")))
def do_testAstrometry(self, alg, bkgd, control): """Test that we can instantiate and play with a centroiding algorithm. """ schema = afwTable.SourceTable.makeMinimalSchema() schema.getAliasMap().set("slot_Centroid", "test") centroider = alg(control, "test", schema) table = afwTable.SourceCatalog(schema) x0, y0 = 12345, 54321 for imageFactory in (afwImage.MaskedImageF, ): im = imageFactory(lsst.geom.ExtentI(100, 100)) im.setXY0(lsst.geom.Point2I(x0, y0)) # This fixed DoubleGaussianPsf replaces a computer generated one. # The values are not anything in particular, just a reasonable size. psf = lsst.afw.detection.GaussianPsf(15, 15, 3.0) exp = afwImage.makeExposure(im) exp.setPsf(psf) im.set(bkgd) x, y = 30, 20 im.image[x, y, afwImage.LOCAL] = 1010 source = table.addNew() spans = afwGeom.SpanSet(exp.getBBox(afwImage.LOCAL)) foot = afwDetection.Footprint(spans) foot.addPeak(x + x0, y + y0, 1010) source.setFootprint(foot) centroider.measure(source, exp) self.assertFloatsAlmostEqual(x + x0, source.getX(), rtol=.00001) self.assertFloatsAlmostEqual(y + y0, source.getY(), rtol=.00001) self.assertFalse(source.get("test_flag")) im.set(bkgd) im.image[10, 20, afwImage.LOCAL] = 1010 im.image[10, 21, afwImage.LOCAL] = 1010 im.image[11, 20, afwImage.LOCAL] = 1010 im.image[11, 21, afwImage.LOCAL] = 1010 x, y = 10.5 + x0, 20.5 + y0 source = table.addNew() source.set('test_x', x) source.set('test_y', y) centroider.measure(source, exp) self.assertFloatsAlmostEqual(x, source.getX(), rtol=.00001) self.assertFloatsAlmostEqual(y, source.getY(), rtol=.00001) self.assertFalse(source.get("test_flag"))
def testFootprintFromBBox1(self): """Create a rectangular Footprint""" x0, y0, w, h = 9, 10, 7, 4 spanSet = afwGeom.SpanSet( lsst.geom.Box2I(lsst.geom.Point2I(x0, y0), lsst.geom.Extent2I(w, h))) foot = afwDetect.Footprint(spanSet) bbox = foot.getBBox() self.assertEqual(bbox.getWidth(), w) self.assertEqual(bbox.getHeight(), h) self.assertEqual(bbox.getMinX(), x0) self.assertEqual(bbox.getMinY(), y0) self.assertEqual(bbox.getMaxX(), x0 + w - 1) self.assertEqual(bbox.getMaxY(), y0 + h - 1)
def testShrink(self): width, height = 5, 10 # Size of footprint x0, y0 = 50, 50 # Position of footprint imwidth, imheight = 100, 100 # Size of image spanSet = afwGeom.SpanSet( lsst.geom.Box2I(lsst.geom.Point2I(x0, y0), lsst.geom.Extent2I(width, height))) region = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(imwidth, imheight)) foot = afwDetect.Footprint(spanSet, region) self.assertEqual(foot.getArea(), width * height) # Add some peaks to the original footprint and check that those lying outside # the shrunken footprint are omitted from the returned shrunken footprint. foot.addPeak(50, 50, 1) # should be omitted in shrunken footprint foot.addPeak(52, 52, 2) # should be kept in shrunken footprint foot.addPeak(50, 59, 3) # should be omitted in shrunken footprint self.assertEqual(len(foot.getPeaks()), 3) # check that all three peaks were added # Shrinking by one pixel makes each dimension *two* pixels shorter. shrunk = afwDetect.Footprint().assign(foot) shrunk.erode(1) self.assertEqual(3 * 8, shrunk.getArea()) # Shrunken footprint should now only contain one peak at (52, 52) self.assertEqual(len(shrunk.getPeaks()), 1) peak = shrunk.getPeaks()[0] self.assertEqual((peak.getIx(), peak.getIy()), (52, 52)) # Without shifting the centroid self.assertEqual(shrunk.getCentroid(), foot.getCentroid()) # Get the same result from a Manhattan shrink shrunk = afwDetect.Footprint().assign(foot) shrunk.erode(1, afwGeom.Stencil.MANHATTAN) self.assertEqual(3 * 8, shrunk.getArea()) self.assertEqual(shrunk.getCentroid(), foot.getCentroid()) # Shrinking by a large amount leaves nothing. shrunkToNothing = afwDetect.Footprint().assign(foot) shrunkToNothing.erode(100) self.assertEqual(shrunkToNothing.getArea(), 0)
def testSplit(self): spanSetOne = afwGeom.SpanSet.fromShape(2, afwGeom.Stencil.BOX).shiftedBy(2, 2) spanSetTwo = afwGeom.SpanSet.fromShape(2, afwGeom.Stencil.BOX).shiftedBy(8, 8) spanSetList = [] for spn in spanSetOne: spanSetList.append(spn) for spn in spanSetTwo: spanSetList.append(spn) spanSetTogether = afwGeom.SpanSet(spanSetList) spanSetSplit = spanSetTogether.split() self.assertEqual(len(spanSetSplit), 2) for a, b in zip(spanSetOne, spanSetSplit[0]): self.assertEqual(a, b) for a, b in zip(spanSetTwo, spanSetSplit[1]): self.assertEqual(a, b)
def testBbox(self): """Add Spans and check bounding box""" foot = afwDetect.Footprint() spanLists = [afwGeom.Span(10, 100, 105), afwGeom.Span(11, 99, 104)] spanSet = afwGeom.SpanSet(spanLists) foot.spans = spanSet bbox = foot.getBBox() self.assertEqual(bbox.getWidth(), 7) self.assertEqual(bbox.getHeight(), 2) self.assertEqual(bbox.getMinX(), 99) self.assertEqual(bbox.getMinY(), 10) self.assertEqual(bbox.getMaxX(), 105) self.assertEqual(bbox.getMaxY(), 11) # clip with a bbox that doesn't overlap at all bbox2 = lsst.geom.Box2I(lsst.geom.Point2I(5, 90), lsst.geom.Extent2I(1, 2)) foot.clipTo(bbox2) self.assertTrue(foot.getBBox().isEmpty()) self.assertEqual(foot.getArea(), 0)
def testEdge(self): task = self.makeSingleFrameMeasurementTask("base_SdssCentroid") exposure, catalog = self.dataset.realize(10.0, task.schema) psfImage = exposure.getPsf().computeImage(self.center) # construct a box that won't fit the full PSF model bbox = psfImage.getBBox() bbox.grow(-5) subImage = lsst.afw.image.ExposureF(exposure, bbox) # we also need to install a smaller footprint, or NoiseReplacer complains before we even get to # measuring the centriod record = catalog[0] spanSet = afwGeom.SpanSet(bbox) newFootprint = lsst.afw.detection.Footprint(spanSet) peak = record.getFootprint().getPeaks()[0] newFootprint.addPeak(peak.getFx(), peak.getFy(), peak.getPeakValue()) record.setFootprint(newFootprint) # just measure the one object we've prepared for task.measure(catalog, subImage) self.assertTrue(record.get("base_SdssCentroid_flag")) self.assertTrue(record.get("base_SdssCentroid_flag_edge"))
def testUnflatten(self): inputArray = np.ones(6) * 4 inputSpanSet = afwGeom.SpanSet([afwGeom.Span(9, 2, 3), afwGeom.Span(10, 3, 4), afwGeom.Span(11, 2, 3)]) outputArray = inputSpanSet.unflatten(inputArray) arrayShape = outputArray.shape bBox = inputSpanSet.getBBox() self.assertEqual(arrayShape[0], bBox.getHeight()) self.assertEqual(arrayShape[1], bBox.getWidth()) # Test unflattening a 2D array spanSetArea = afwGeom.SpanSet.fromShape(2, afwGeom.Stencil.BOX) spanSetArea = spanSetArea.shiftedBy(2, 2) testArray = np.arange(5*5*3).reshape(5*5, 3) unflattened3DArray = spanSetArea.unflatten(testArray) truthArray = np.arange(5*5*3).reshape(5, 5, 3) self.assertFloatsAlmostEqual(unflattened3DArray, truthArray)
def testFootprintFromBBox1(self): """Create a rectangular Footprint""" x0, y0, w, h = 9, 10, 7, 4 spanSet = afwGeom.SpanSet(lsst.geom.Box2I(lsst.geom.Point2I(x0, y0), lsst.geom.Extent2I(w, h))) foot = afwDetect.Footprint(spanSet) bbox = foot.getBBox() self.assertEqual(bbox.getWidth(), w) self.assertEqual(bbox.getHeight(), h) self.assertEqual(bbox.getMinX(), x0) self.assertEqual(bbox.getMinY(), y0) self.assertEqual(bbox.getMaxX(), x0 + w - 1) self.assertEqual(bbox.getMaxY(), y0 + h - 1) if False: idImage = afwImage.ImageU(w, h) idImage.set(0) foot.insertIntoImage(idImage, foot.getId(), bbox) ds9.mtv(idImage, frame=2)
def testCircle(self): xc, yc = 30, 50 radius = 10 spanSet = afwGeom.SpanSet.fromShape(radius).shiftedBy(xc, yc) test = afwDet.Footprint(spanSet) # Here's how it used to be done using circles, before #1556 r2 = int(radius**2 + 0.5) r = int(math.sqrt(r2)) spanList = [] for i in range(-r, r + 1): hlen = int(math.sqrt(r2 - i**2)) spanList.append(afwGeom.Span(yc + i, xc - hlen, xc + hlen)) control = afwDet.Footprint(afwGeom.SpanSet(spanList)) self.assertEqual(len(test.getSpans()), len(control.getSpans())) for s0, s1 in zip(test.getSpans(), control.getSpans()): self.assertEqual(s0.getX0(), s1.getX0()) self.assertEqual(s0.getX1(), s1.getX1()) self.assertEqual(s0.getY(), s1.getY()) self.assertEqual(test.getArea(), control.getArea())