Beispiel #1
0
 def testConvolution(self):
     if scipy is None:
         print("Skipping convolution test; scipy could not be imported.")
         return
     e1 = ellipses.Ellipse(ellipses.Axes(10, 8, 0.3),
                           geom.Point2D(1.5, 2.0))
     e2 = ellipses.Ellipse(ellipses.Axes(12, 9, -0.5),
                           geom.Point2D(-1.0, -0.25))
     f1 = lsst.shapelet.ShapeletFunction(3, lsst.shapelet.HERMITE, e1)
     f2 = lsst.shapelet.ShapeletFunction(2, lsst.shapelet.LAGUERRE, e2)
     f1.getCoefficients()[:] = np.random.randn(*f1.getCoefficients().shape)
     f2.getCoefficients()[:] = np.random.randn(*f2.getCoefficients().shape)
     fc1, fc2 = self.checkConvolution(f1, f2)
     self.assertEqual(fc1.getBasisType(), lsst.shapelet.HERMITE)
     self.assertEqual(fc2.getBasisType(), lsst.shapelet.LAGUERRE)
     self.assertFloatsAlmostEqual(fc1.getEllipse().getParameterVector(),
                                  fc2.getEllipse().getParameterVector())
     self.assertEqual(fc1.getOrder(), fc2.getOrder())
     fc2.changeBasisType(lsst.shapelet.HERMITE)
     self.assertFloatsAlmostEqual(fc1.getCoefficients(),
                                  fc2.getCoefficients(), 1E-8)
Beispiel #2
0
    def _fig8Test(self, x1, y1, x2, y2):
        # Construct a "figure of 8" consisting of two circles touching at the
        # centre of an image, then demonstrate that it shrinks correctly.
        # (Helper method for tests below.)
        radius = 3
        imwidth, imheight = 100, 100
        nshrink = 1

        # These are the correct values for footprint sizes given the paramters
        # above.
        circle_npix = 29
        initial_npix = circle_npix * 2 - 1 # touch at one pixel
        shrunk_npix = 26

        box = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(imwidth, imheight))

        e1 = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                                          afwGeom.Point2D(x1, y1))
        f1 = afwDetect.Footprint(e1,box)
        self.assertEqual(f1.getNpix(), circle_npix)

        e2 = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                                          afwGeom.Point2D(x2, y2))
        f2 = afwDetect.Footprint(e2,box)
        self.assertEqual(f2.getNpix(), circle_npix)

        initial = afwDetect.mergeFootprints(f1, f2)
        initial.setRegion(f2.getRegion()) # merge does not propagate the region
        self.assertEqual(initial_npix, initial.getNpix())

        shrunk = afwDetect.shrinkFootprint(initial, nshrink, True)
        self.assertEqual(shrunk_npix, shrunk.getNpix())

        if display:
            idImage = afwImage.ImageU(imwidth, imheight)
            for i, foot in enumerate([initial, shrunk]):
                print foot.getNpix()
                foot.insertIntoImage(idImage, i+1);
            ds9.mtv(idImage)
Beispiel #3
0
    def testShrinkIsoVsManhattan(self):
        # Demonstrate that isotropic and Manhattan shrinks are different.
        radius = 8
        imwidth, imheight = 100, 100
        x0, y0 = imwidth//2, imheight//2
        nshrink = 4

        ellipse = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(1.5*radius, 2*radius, 0),
                                          afwGeom.Point2D(x0,y0))
        foot = afwDetect.Footprint(ellipse, afwGeom.Box2I(afwGeom.Point2I(0, 0),
                                   afwGeom.Extent2I(imwidth, imheight)))
        self.assertNotEqual(afwDetect.shrinkFootprint(foot, nshrink, False),
                            afwDetect.shrinkFootprint(foot, nshrink, True))
Beispiel #4
0
 def testModel3(self):
     amplitude = 3.2
     radius = 2.7
     psfEllipse = ellipses.Quadrupole(2.3, 1.8, 0.6)
     psfAmplitude = 5.3
     mgc = ms.GaussianComponent(amplitude, radius)
     shapelet = mgc.makeShapelet(ellipses.Ellipse(self.ellipse))
     psf = ms.GaussianComponent(psfAmplitude, 1.0).makeShapelet(
         ellipses.Ellipse(psfEllipse))
     shapelet = shapelet.convolve(psf)
     builder = ms.GaussianModelBuilder(self.x, self.y, amplitude, radius,
                                       psfEllipse, psfAmplitude)
     builder.update(self.ellipse)
     self.ellipse.scale(radius)
     ellipse = self.ellipse.convolve(psfEllipse)
     self.assertClose(builder.getModel(),
                      amplitude * psfAmplitude * self.buildModel(ellipse))
     z0 = builder.getModel()
     z1 = psfAmplitude * amplitude * self.buildModel(ellipse)
     z2 = self.evalShapelets(shapelet)
     self.assertClose(z0, z1)
     self.assertClose(z0, z2)
Beispiel #5
0
 def testModel2(self):
     amplitude = 3.2
     radius = 2.7
     mgc = ms.GaussianComponent(amplitude, radius)
     shapelet = mgc.makeShapelet(ellipses.Ellipse(self.ellipse))
     builder = ms.GaussianModelBuilder(self.x, self.y, amplitude, radius)
     builder.update(self.ellipse)
     self.ellipse.scale(radius)
     z0 = builder.getModel()
     z1 = amplitude * self.buildModel(self.ellipse)
     z2 = self.evalShapelets(shapelet)
     self.assertClose(z0, z1)
     self.assertClose(z0, z2)
Beispiel #6
0
    def testFootprintFromCircle(self):
        """Create an elliptical Footprint"""
        ellipse = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(6, 6, 0),
                                          afwGeom.Point2D(9, 15))
        foot = afwDetect.Footprint(
            ellipse,
            afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(20, 30)))

        idImage = afwImage.ImageU(
            afwGeom.Extent2I(foot.getRegion().getWidth(),
                             foot.getRegion().getHeight()))
        idImage.set(0)

        foot.insertIntoImage(idImage, foot.getId())

        if False:
            ds9.mtv(idImage, frame=2)
 def setUp(self):
     np.random.seed(500)
     order = 4
     self.ellipse = ellipses.Ellipse(ellipses.Axes(2.2, 0.8, 0.3), geom.Point2D(0.12, -0.08))
     self.coefficients = np.random.randn(lsst.shapelet.computeSize(order))
     self.x = np.random.randn(25)
     self.y = np.random.randn(25)
     self.bases = [
         lsst.shapelet.BasisEvaluator(order, lsst.shapelet.HERMITE),
         lsst.shapelet.BasisEvaluator(order, lsst.shapelet.LAGUERRE),
     ]
     self.functions = [
         lsst.shapelet.ShapeletFunction(order, lsst.shapelet.HERMITE, self.coefficients),
         lsst.shapelet.ShapeletFunction(order, lsst.shapelet.LAGUERRE, self.coefficients),
     ]
     for function in self.functions:
         function.setEllipse(self.ellipse)
Beispiel #8
0
 def testTablePersistence(self):
     ellipse = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(8, 6, 0.25), afwGeom.Point2D(9,15))
     fp1 = afwDetect.Footprint(ellipse)
     fp1.addPeak(6, 7, 2)
     fp1.addPeak(8, 9, 3)
     with utilsTests.getTempFilePath(".fits") as tmpFile:
         fp1.writeFits(tmpFile)
         fp2 = afwDetect.Footprint.readFits(tmpFile)
         self.assertEqual(fp1.getArea(), fp2.getArea())
         self.assertEqual(list(fp1.getSpans()), list(fp2.getSpans()))
         # can't use Peak operator== for comparison because it compares IDs, not positions/values
         self.assertEqual(len(fp1.getPeaks()), len(fp2.getPeaks()))
         for peak1, peak2 in zip(fp1.getPeaks(), fp2.getPeaks()):
             self.assertEqual(peak1.getIx(), peak2.getIx())
             self.assertEqual(peak1.getIy(), peak2.getIy())
             self.assertEqual(peak1.getFx(), peak2.getFx())
             self.assertEqual(peak1.getFy(), peak2.getFy())
             self.assertEqual(peak1.getPeakValue(), peak2.getPeakValue())
Beispiel #9
0
 def testTablePersistence(self):
     ellipse = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(8, 6, 0.25),
                                       afwGeom.Point2D(9, 15))
     fp1 = afwDetect.Footprint(ellipse)
     fp1.addPeak(6, 7, 2)
     fp1.addPeak(8, 9, 3)
     filename = "testFootprintTablePersistence.fits"
     fp1.writeFits(filename)
     fp2 = afwDetect.Footprint.readFits(filename)
     self.assertEqual(fp1.getArea(), fp2.getArea())
     self.assertEqual(list(fp1.getSpans()), list(fp2.getSpans()))
     self.assertEqual(len(fp1.getPeaks()), len(fp2.getPeaks()))
     for peak1, peak2 in zip(fp1.getPeaks(), fp2.getPeaks()):
         self.assertEqual(peak1.getIx(), peak2.getIx())
         self.assertEqual(peak1.getIy(), peak2.getIy())
         self.assertEqual(peak1.getFx(), peak2.getFx())
         self.assertEqual(peak1.getFy(), peak2.getFy())
         self.assertEqual(peak1.getPeakValue(), peak2.getPeakValue())
     os.remove(filename)
Beispiel #10
0
    def testShrinkIsoVsManhattan(self):
        # Demonstrate that isotropic and Manhattan shrinks are different.
        radius = 8
        imwidth, imheight = 100, 100
        x0, y0 = imwidth // 2, imheight // 2
        nshrink = 4

        ellipse = afwGeomEllipses.Ellipse(
            afwGeomEllipses.Axes(1.5 * radius, 2 * radius, 0),
            afwGeom.Point2D(x0, y0))
        spanSet = afwGeom.SpanSet.fromShape(ellipse)
        foot = afwDetect.Footprint(
            spanSet,
            afwGeom.Box2I(afwGeom.Point2I(0, 0),
                          afwGeom.Extent2I(imwidth, imheight)))
        footIsotropic = afwDetect.Footprint()
        footIsotropic.assign(foot)

        foot.erode(nshrink, afwGeom.Stencil.MANHATTAN)
        footIsotropic.erode(nshrink)
        self.assertNotEqual(foot, footIsotropic)
Beispiel #11
0
    def testFootprintFromEllipse(self):
        """Create an elliptical Footprint"""
        cen = afwGeom.Point2D(23, 25)
        a, b, theta = 25, 15, 30
        ellipse = afwGeomEllipses.Ellipse(
            afwGeomEllipses.Axes(a, b, math.radians(theta)), cen)
        spanSet = afwGeom.SpanSet.fromShape(ellipse)
        foot = afwDetect.Footprint(
            spanSet,
            afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(50, 60)))

        idImage = afwImage.ImageU(
            afwGeom.Extent2I(foot.getRegion().getWidth(),
                             foot.getRegion().getHeight()))
        idImage.set(0)

        foot.spans.setImage(idImage, foot.getId())

        if display:
            ds9.mtv(idImage, frame=2)
            displayUtils.drawFootprint(foot, frame=2)
            shape = foot.getShape()
            shape.scale(2)  # <r^2> = 1/2 for a disk
            ds9.dot(shape, *cen, frame=2, ctype=ds9.RED)

            shape = foot.getShape()
            shape.scale(2)  # <r^2> = 1/2 for a disk
            ds9.dot(shape, *cen, frame=2, ctype=ds9.MAGENTA)

        axes = afwGeom.ellipses.Axes(foot.getShape())
        axes.scale(2)  # <r^2> = 1/2 for a disk

        self.assertEqual(foot.getCentroid(), cen)
        self.assertLess(abs(a - axes.getA()), 0.15,
                        "a: %g v. %g" % (a, axes.getA()))
        self.assertLess(abs(b - axes.getB()), 0.02,
                        "b: %g v. %g" % (b, axes.getB()))
        self.assertLess(
            abs(theta - math.degrees(axes.getTheta())), 0.2,
            "theta: %g v. %g" % (theta, math.degrees(axes.getTheta())))
Beispiel #12
0
    def testClipToNonzero(self):
        # create a circular footprint
        ellipse = afwGeomEllipses.Ellipse(afwGeomEllipses.Axes(6, 6, 0),
                                          afwGeom.Point2D(9, 15))
        bb = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(20, 30))
        foot = afwDetect.Footprint(ellipse, bb)

        a0 = foot.getArea()

        plots = False
        if plots:
            import matplotlib
            matplotlib.use('Agg')
            import pylab as plt

            plt.clf()
            img = afwImage.ImageU(bb)
            foot.insertIntoImage(img, 1)
            ima = dict(interpolation='nearest', origin='lower', cmap='gray')
            plt.imshow(img.getArray(), **ima)
            plt.savefig('clipnz1.png')

        source = afwImage.ImageF(bb)
        source.getArray()[:, :] = 1.
        source.getArray()[:, 0:10] = 0.

        foot.clipToNonzero(source)
        foot.normalize()
        a1 = foot.getArea()
        self.assertLess(a1, a0)

        img = afwImage.ImageU(bb)
        foot.insertIntoImage(img, 1)
        self.assertTrue(np.all(img.getArray()[source.getArray() == 0] == 0))

        if plots:
            plt.clf()
            plt.subplot(1, 2, 1)
            plt.imshow(source.getArray(), **ima)
            plt.subplot(1, 2, 2)
            plt.imshow(img.getArray(), **ima)
            plt.savefig('clipnz2.png')

        source.getArray()[:12, :] = 0.
        foot.clipToNonzero(source)
        foot.normalize()

        a2 = foot.getArea()
        self.assertLess(a2, a1)

        img = afwImage.ImageU(bb)
        foot.insertIntoImage(img, 1)
        self.assertTrue(np.all(img.getArray()[source.getArray() == 0] == 0))

        if plots:
            plt.clf()
            plt.subplot(1, 2, 1)
            plt.imshow(source.getArray(), **ima)
            plt.subplot(1, 2, 2)
            img = afwImage.ImageU(bb)
            foot.insertIntoImage(img, 1)
            plt.imshow(img.getArray(), **ima)
            plt.savefig('clipnz3.png')
    def measureKronInPython(self,
                            objImg,
                            xcen,
                            ycen,
                            nsigma,
                            kfac,
                            nIterForRadius,
                            makeImage=None):
        """Measure the Kron quantities of an elliptical Gaussian in python.

        N.b. only works for XY0 == (0, 0)
        """
        #
        # Measure moments using SDSS shape algorithm
        #
        # Note: this code was converted to the new meas_framework, but is not exercised.
        msConfig = makeMeasurementConfig(False, nsigma, nIterForRadius, kfac)
        center = afwGeom.Point2D(xcen, ycen)
        source = self.measureFree(objImg, center, msConfig)
        algMeta = source.getTable().getMetadata()
        self.assertTrue(
            algMeta.exists('ext_photometryKron_KronFlux_nRadiusForFlux'))

        Mxx = source.getIxx()
        Mxy = source.getIxy()
        Myy = source.getIyy()
        #
        # Calculate principal axes
        #
        Muu_p_Mvv = Mxx + Myy
        Muu_m_Mvv = math.sqrt((Mxx - Myy)**2 + 4 * Mxy**2)
        Muu = 0.5 * (Muu_p_Mvv + Muu_m_Mvv)
        Mvv = 0.5 * (Muu_p_Mvv - Muu_m_Mvv)
        theta = 0.5 * math.atan2(2 * Mxy, Mxx - Myy)
        a = math.sqrt(Muu)
        b = math.sqrt(Mvv)
        ab = a / b
        #
        # Get footprint
        #
        ellipse = afwEllipses.Ellipse(
            afwEllipses.Axes(nsigma * a, nsigma * b, theta),
            afwGeom.Point2D(xcen, ycen))
        fpEllipse = afwDetection.Footprint(ellipse)

        sumI = 0.0
        sumR = (0.38259771140356325 / ab *
                (1 + math.sqrt(2) *
                 math.hypot(math.fmod(xcen, 1), math.fmod(ycen, 1))) *
                objImg.image[int(xcen), int(ycen), afwImage.LOCAL])

        gal = objImg.image

        c, s = math.cos(theta), math.sin(theta)
        for sp in fpEllipse.getSpans():
            y, x0, x1 = sp.getY(), sp.getX0(), sp.getX1()

            for x in range(x0, x1 + 1):
                dx, dy = x - xcen, y - ycen
                u = c * dx + s * dy
                v = -s * dx + c * dy

                r = math.hypot(u, v * ab)
                try:
                    val = gal[x, y, afwImage.LOCAL]
                except Exception:
                    continue

                sumI += val
                sumR += val * r

        R_K = sumR / sumI

        sumI = 0.0
        for y in range(self.height):
            for x in range(self.width):
                dx, dy = x - xcen, y - ycen
                u = c * dx + s * dy
                v = -s * dx + c * dy
                if math.hypot(u / a, v / b) < kfac:
                    sumI += gal[x, y, afwImage.LOCAL]

        return R_K, sumI, 0, False, False, False
Beispiel #14
0
 def testSpanSetFromEllipse(self):
     axes = afwGeomEllipses.Axes(6, 6, 0)
     ellipse = afwGeomEllipses.Ellipse(axes, afwGeom.Point2D(5, 6))
     spanSet = afwGeom.SpanSet.fromShape(ellipse)
     for ss, es in zip(spanSet, afwGeomEllipses.PixelRegion(ellipse)):
         self.assertEqual(ss, es)
Beispiel #15
0
    def measureKronInPython(self, objImg, xcen, ycen, nsigma, kfac, nIterForRadius, makeImage=None):
        """Measure the Kron quantities of an elliptical Gaussian in python

        N.b. only works for XY0 == (0, 0)
        """
        #
        # Measure moments using SDSS shape algorithm
        #
        msConfig = measAlg.SourceMeasurementConfig()
        if False:                       # requires #2546
            msConfig.centroider = None
            msConfig.slots.centroid = None

        schema = afwTable.SourceTable.makeMinimalSchema()
        ms = msConfig.makeMeasureSources(schema)
        table = afwTable.SourceTable.make(schema)
        msConfig.slots.setupTable(table)
        source = table.makeRecord()
        fp = afwDetection.Footprint(objImg.getBBox())
        source.setFootprint(fp)
        center = afwGeom.Point2D(xcen, ycen)
        ms.apply(source, objImg, center)

        Mxx = source.getIxx()
        Mxy = source.getIxy()
        Myy = source.getIyy()
        #
        # Calculate principal axes
        #
        Muu_p_Mvv = Mxx + Myy
        Muu_m_Mvv = math.sqrt((Mxx - Myy)**2 + 4*Mxy**2)
        Muu = 0.5*(Muu_p_Mvv + Muu_m_Mvv)
        Mvv = 0.5*(Muu_p_Mvv - Muu_m_Mvv)
        theta = 0.5*math.atan2(2*Mxy, Mxx - Myy)
        a = math.sqrt(Muu)
        b = math.sqrt(Mvv)
        ab = a/b
        #
        # Get footprint
        #
        ellipse = afwEllipses.Ellipse(afwEllipses.Axes(nsigma*a, nsigma*b, theta),
                                      afwGeom.Point2D(xcen - objImg.getX0(), ycen - objImg.getY0()))
        fpEllipse = afwDetection.Footprint(ellipse)
        
        sumI = 0.0
        sumR = 0.38259771140356325/ab*(1 + math.sqrt(2)*math.hypot(math.fmod(xcen, 1), math.fmod(ycen, 1)))*\
               objImg.getMaskedImage().getImage().get(int(xcen), int(ycen))
               
        gal = objImg.getMaskedImage().getImage()

        c, s = math.cos(theta), math.sin(theta)
        for sp in fpEllipse.getSpans():
            y, x0, x1 = sp.getY(), sp.getX0(), sp.getX1()

            for x in range(x0, x1 + 1):
                dx, dy = x - xcen, y - ycen
                u =  c*dx + s*dy
                v = -s*dx + c*dy

                r = math.hypot(u, v*ab)
                try:
                    val = gal.get(x, y)
                except:
                    continue

                sumI += val
                sumR += val*r

        R_K = sumR/sumI

        sumI = 0.0
        for y in range(self.height):
            for x in range(self.width):
                dx, dy = x - xcen, y - ycen
                u =  c*dx + s*dy
                v = -s*dx + c*dy
                if math.hypot(u/a, v/b) < kfac:
                    sumI += gal.get(x, y)

        return R_K, sumI, 0, False, False, False
Beispiel #16
0
    def testShapeletApproximations(self):
        psf0 = lsst.shapelet.ShapeletFunction(0, lsst.shapelet.HERMITE,
                                              PSF_SIGMA)
        psf0.getCoefficients(
        )[:] = 1.0 / lsst.shapelet.ShapeletFunction.FLUX_FACTOR
        psf = lsst.shapelet.MultiShapeletFunction()
        psf.addComponent(psf0)
        psf.normalize()
        ellipse = el.Separable[el.Distortion,
                               el.DeterminantRadius](E1, E2, GALAXY_RADIUS)
        for name, nComponents, maxRadius in PROFILES:
            # check1 is the multi-Gaussian approximation, as convolved and evaluated by GalSim,
            check1 = lsst.afw.image.ImageD(
                os.path.join("tests", "data",
                             name + "-approx.fits")).getArray()
            xc = check1.shape[1] // 2
            yc = check1.shape[0] // 2
            xb = np.arange(check1.shape[1], dtype=float) - xc
            yb = np.arange(check1.shape[0], dtype=float) - yc
            xg, yg = np.meshgrid(xb, yb)

            basis = lsst.shapelet.RadialProfile.get(name).getBasis(
                nComponents, maxRadius)
            builder = lsst.shapelet.MatrixBuilderD.Factory(
                xg.ravel(), yg.ravel(), basis, psf)()
            image1 = np.zeros(check1.shape, dtype=float)
            matrix = image1.reshape(check1.size, 1)
            builder(matrix, el.Ellipse(ellipse))
            self.assertFloatsAlmostEqual(check1,
                                         image1,
                                         plotOnFailure=False,
                                         rtol=5E-5,
                                         relTo=check1.max())
            msf = basis.makeFunction(
                el.Ellipse(ellipse, lsst.afw.geom.Point2D(xc, yc)),
                np.array([1.0], dtype=float))
            msf = msf.convolve(psf)
            image2 = np.zeros(check1.shape, dtype=float)
            msf.evaluate().addToImage(lsst.afw.image.ImageD(image2, False))
            self.assertFloatsAlmostEqual(check1,
                                         image2,
                                         plotOnFailure=False,
                                         rtol=5E-5,
                                         relTo=check1.max())

            if name == 'exp':
                # check2 is the exact profile, again by GalSim.
                # We only check exp against the exact profile.  The other approximations are less
                # accurate, and we only really need to test one.  The real measure of whether these
                # profiles are good enough is more complicated than what we can do in a unit test.
                check2 = lsst.afw.image.ImageD(
                    os.path.join("tests", "data",
                                 name + "-exact.fits")).getArray()
                self.assertFloatsAlmostEqual(check2,
                                             image1,
                                             plotOnFailure=False,
                                             rtol=1E-3,
                                             relTo=check2.max())

            if CHECK_COMPONENT_IMAGES:
                # This was once useful for debugging test failures, and may be again, but it's
                # redundant with the above and requires putting more check images in git, so
                # it's disabled by default.
                for n, sf in enumerate(msf.getComponents()):
                    check = lsst.afw.image.ImageD(
                        os.path.join("tests", "data", "%s-approx-%0d.fits" %
                                     (name, n))).getArray()
                    image = np.zeros(check1.shape, dtype=float)
                    sf.evaluate().addToImage(
                        lsst.afw.image.ImageD(image, False))
                    self.assertFloatsAlmostEqual(check,
                                                 image,
                                                 plotOnFailure=False,
                                                 rtol=5E-5,
                                                 relTo=check1.max())