Ejemplo n.º 1
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 = lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
                              lsst.geom.Extent2I(imwidth, imheight))

        e1 = afwGeom.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                             lsst.geom.Point2D(x1, y1))
        spanSet1 = afwGeom.SpanSet.fromShape(e1)
        f1 = afwDetect.Footprint(spanSet1, box)
        self.assertEqual(f1.getArea(), circle_npix)

        e2 = afwGeom.Ellipse(afwGeomEllipses.Axes(radius, radius, 0),
                             lsst.geom.Point2D(x2, y2))
        spanSet2 = afwGeom.SpanSet.fromShape(e2)
        f2 = afwDetect.Footprint(spanSet2, box)
        self.assertEqual(f2.getArea(), circle_npix)

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

        shrunk = afwDetect.Footprint().assign(initial)
        shrunk.erode(nshrink)
        self.assertEqual(shrunk_npix, shrunk.getArea())

        if display:
            idImage = afwImage.ImageU(imwidth, imheight)
            for i, foot in enumerate([initial, shrunk]):
                print(foot.getArea())
                foot.spans.setImage(idImage, i + 1)
            afwDisplay.Display(frame=1).mtv(idImage,
                                            title=self._testMethodName +
                                            " image")
Ejemplo n.º 2
0
    def testFootprintFromCircle(self):
        """Create an elliptical Footprint"""
        ellipse = afwGeom.Ellipse(afwGeomEllipses.Axes(6, 6, 0),
                                  lsst.geom.Point2D(9, 15))
        spanSet = afwGeom.SpanSet.fromShape(ellipse)
        foot = afwDetect.Footprint(spanSet,
                                   lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
                                                   lsst.geom.Extent2I(20, 30)))

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

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

        if False:
            ds9.mtv(idImage, frame=2)
Ejemplo n.º 3
0
 def testTablePersistence(self):
     ellipse = afwGeom.Ellipse(afwGeomEllipses.Axes(8, 6, 0.25),
                               lsst.geom.Point2D(9, 15))
     fp1 = afwDetect.Footprint(afwGeom.SpanSet.fromShape(ellipse))
     fp1.addPeak(6, 7, 2)
     fp1.addPeak(8, 9, 3)
     with lsst.utils.tests.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())
Ejemplo n.º 4
0
    def testFootprintFromEllipse(self):
        """Create an elliptical Footprint"""
        cen = lsst.geom.Point2D(23, 25)
        a, b, theta = 25, 15, 30
        ellipse = afwGeom.Ellipse(
            afwGeomEllipses.Axes(a, b, math.radians(theta)), cen)
        spanSet = afwGeom.SpanSet.fromShape(ellipse)
        foot = afwDetect.Footprint(
            spanSet,
            lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
                            lsst.geom.Extent2I(50, 60)))

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

        foot.spans.setImage(idImage, 42)

        if display:
            disp = afwDisplay.Display(frame=2)
            disp.mtv(idImage, title=self._testMethodName + " image")
            afwDisplay.utils.drawFootprint(foot, frame=2)
            shape = foot.getShape()
            shape.scale(2)  # <r^2> = 1/2 for a disk
            disp.dot(shape, *cen, ctype=afwDisplay.RED)

            shape = foot.getShape()
            shape.scale(2)  # <r^2> = 1/2 for a disk
            disp.dot(shape, *cen, ctype=afwDisplay.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,
                        f"a: {a:g} vs. {axes.getA():g}")
        self.assertLess(abs(b - axes.getB()), 0.02,
                        f"b: {b:g} va. {axes.getB():g}")
        self.assertLess(
            abs(theta - math.degrees(axes.getTheta())), 0.2,
            f"theta: {theta:g} vs. {math.degrees(axes.getTheta()):g}")
Ejemplo n.º 5
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 = afwGeom.Ellipse(
            afwGeomEllipses.Axes(1.5 * radius, 2 * radius, 0),
            lsst.geom.Point2D(x0, y0))
        spanSet = afwGeom.SpanSet.fromShape(ellipse)
        foot = afwDetect.Footprint(
            spanSet,
            lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
                            lsst.geom.Extent2I(imwidth, imheight)))
        footIsotropic = afwDetect.Footprint()
        footIsotropic.assign(foot)

        foot.erode(nshrink, afwGeom.Stencil.MANHATTAN)
        footIsotropic.erode(nshrink)
        self.assertNotEqual(foot, footIsotropic)
Ejemplo n.º 6
0
    def testFootprintFromEllipse(self):
        """Create an elliptical Footprint"""
        cen = afwGeom.Point2D(23, 25)
        a, b, theta = 25, 15, 30
        ellipse = afwGeom.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())))
Ejemplo n.º 7
0
    def testEllipticalGaussian(self):
        """Test measuring elliptical aperture mags for an elliptical Gaussian"""

        width, height = 200, 200
        xcen, ycen = 0.5 * width, 0.5 * height
        #
        # Make the object
        #
        gal = afwImage.ImageF(lsst.geom.ExtentI(width, height))
        a, b, theta = float(10), float(5), 20
        instFlux = 1e4
        I0 = instFlux / (2 * math.pi * a * b)

        c, s = math.cos(math.radians(theta)), math.sin(math.radians(theta))
        for y in range(height):
            for x in range(width):
                dx, dy = x - xcen, y - ycen
                u = c * dx + s * dy
                v = -s * dx + c * dy
                val = I0 * math.exp(-0.5 * ((u / a)**2 + (v / b)**2))
                if val < 0:
                    val = 0
                gal[x, y, afwImage.LOCAL] = val

        objImg = afwImage.makeExposure(afwImage.makeMaskedImage(gal))
        del gal

        if display:
            frame = 0
            ds9.mtv(objImg, frame=frame, title="Elliptical")

        self.assertAlmostEqual(
            1.0,
            afwMath.makeStatistics(objImg.getMaskedImage().getImage(),
                                   afwMath.SUM).getValue() / instFlux)
        #
        # Now measure some annuli
        #
        for r1, r2 in [
            (0., 0.45 * a),
            (0.45 * a, 1.0 * a),
            (1.0 * a, 2.0 * a),
            (2.0 * a, 3.0 * a),
            (3.0 * a, 5.0 * a),
            (3.0 * a, 10.0 * a),
        ]:
            if display:  # draw the inner and outer boundaries of the aperture
                Mxx = 1
                Myy = (b / a)**2

                mxx, mxy, myy = c**2 * Mxx + s**2 * Myy, c * s * (
                    Mxx - Myy), s**2 * Mxx + c**2 * Myy
                for r in (r1, r2):
                    ds9.dot("@:%g,%g,%g" %
                            (r**2 * mxx, r**2 * mxy, r**2 * myy),
                            xcen,
                            ycen,
                            frame=frame)

            center = lsst.geom.Point2D(xcen, ycen)

            # this tests tests a sync algorithm with an inner and outer radius
            # since that is no longer available from the ApertureFluxAlgorithm,
            # we will calculate the two and subtract.

            axes = afwGeom.ellipses.Axes(r2, r2 * (1 - b / a),
                                         math.radians(theta))
            ellipse = afwGeom.Ellipse(axes, center)
            result2 = measBase.ApertureFluxAlgorithm.computeSincFlux(
                objImg.getMaskedImage(), ellipse)

            axes = afwGeom.ellipses.Axes(r1, r1 * (1 - b / a),
                                         math.radians(theta))
            ellipse = afwGeom.Ellipse(axes, center)
            result1 = measBase.ApertureFluxAlgorithm.computeSincFlux(
                objImg.getMaskedImage(), ellipse)

            self.assertAlmostEqual(
                math.exp(-0.5 * (r1 / a)**2) - math.exp(-0.5 * (r2 / a)**2),
                (result2.instFlux - result1.instFlux) / instFlux, 4)
Ejemplo n.º 8
0
def main():

    ########################################################################
    # command line arguments and options
    ########################################################################

    parser = optparse.OptionParser(usage=__doc__)
    # parser.add_option("-a", "--aa", dest="aa", type=float,
    #                  default=1.0, help="default=%default")

    opts, args = parser.parse_args()

    if len(args) == 0:
        r1, r2, dr = 3.0, 3.0, 0.5
    elif len(args) == 3:
        r1, r2, dr = list(map(float, args))
    else:
        parser.print_help()
        sys.exit(1)

    # make a list of radii to compute the growthcurve points
    radius = []
    nR = int((r2 - r1) / dr + 1)
    for iR in range(nR):
        radius.append(r1 + iR * dr)

    # make an image big enough to hold the largest requested aperture
    xwidth = 2 * (0 + 128)
    ywidth = xwidth

    # initializations
    sigmas = [1.5, 2.5]  # the Gaussian widths of the psfs we'll use
    nS = len(sigmas)
    alg = measBase.PsfFluxAlgorithm
    schema = afwTable.SourceTable.makeMinimalSchema()
    schema.addField("centroid_x", type=float)
    schema.addField("centroid_y", type=float)
    plugin = alg(measBase.PsfFluxControl(), "test", schema)
    cat = afwTable.SourceCatalog(schema)
    cat.defineCentroid("centroid")
    print("# sig rad  Naive Sinc Psf")
    for iS in range(nS):
        sigma = sigmas[iS]

        # make a Gaussian star to measure
        gauss = afwMath.GaussianFunction2D(sigma, sigma)
        kernel = afwMath.AnalyticKernel(xwidth, ywidth, gauss)
        kimg = afwImage.ImageD(kernel.getDimensions())
        kernel.computeImage(kimg, False)
        kimg *= 100.0
        mimg = afwImage.MaskedImageF(
            kimg.convertFloat(), afwImage.Mask(kimg.getDimensions(), 0x0),
            afwImage.ImageF(kimg.getDimensions(), 0.0))
        exposure = afwImage.ExposureF(mimg)

        # loop over all the radii in the growthcurve
        for iR in range(nR):

            psfH = int(2.0 * (r2 + 2.0)) + 1
            psfW = int(2.0 * (r2 + 2.0)) + 1

            # this test uses a single Gaussian instead of the original double gaussian
            psf = afwDet.GaussianPsf(psfW, psfH, sigma)

            # get the aperture fluxes for Naive and Sinc methods

            axes = afwGeom.ellipses.Axes(radius[iR], radius[iR],
                                         math.radians(0))
            center = afwGeom.Point2D(0, 0)
            ellipse = afwGeom.Ellipse(axes, center)
            resultSinc = measBase.ApertureFluxAlgorithm.computeSincFlux(
                mimg.getImage(), ellipse)
            resultNaive = measBase.ApertureFluxAlgorithm.computeNaiveFlux(
                mimg.getImage(), ellipse)
            source = cat.addNew()
            source["centroid_x"] = 0
            source["centroid_y"] = 0
            exposure.setPsf(psf)
            plugin.measure(source, exposure)
            fluxNaive = resultNaive.flux
            fluxSinc = resultSinc.flux
            fluxPsf = source["test_flux"]

            # get the exact flux for the theoretical smooth PSF
            # rpsf = RGaussian(sigma, a, radius[iR], aptaper)
            # *** not sure how to integrate a python functor ***

            print("%.2f %.2f  %.3f %.3f %.3f" %
                  (sigma, radius[iR], fluxNaive, fluxSinc, fluxPsf))
Ejemplo n.º 9
0
 def testSpanSetFromEllipse(self):
     axes = afwGeomEllipses.Axes(6, 6, 0)
     ellipse = afwGeom.Ellipse(axes, afwGeom.Point2D(5, 6))
     spanSet = afwGeom.SpanSet.fromShape(ellipse)
     for ss, es in zip(spanSet, afwGeomEllipses.PixelRegion(ellipse)):
         self.assertEqual(ss, es)