Esempio n. 1
0
    def testMakeBadKernels(self):
        """Attempt to make various invalid kernels; make sure the constructor shows an exception
        """
        kWidth = 4
        kHeight = 3

        gaussFunc1 = afwMath.GaussianFunction1D(1.0)
        gaussFunc2 = afwMath.GaussianFunction2D(1.0, 1.0, 0.0)
        spFunc = afwMath.PolynomialFunction2D(1)
        kernelList = []
        kernelList.append(
            afwMath.FixedKernel(
                afwImage.ImageD(lsst.geom.Extent2I(kWidth, kHeight), 0.1)))
        kernelList.append(
            afwMath.FixedKernel(
                afwImage.ImageD(lsst.geom.Extent2I(kWidth, kHeight), 0.2)))

        for numKernelParams in (2, 4):
            spFuncList = []
            for ii in range(numKernelParams):
                spFuncList.append(spFunc.clone())
            try:
                afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc2, spFuncList)
                self.fail(
                    "Should have failed with wrong # of spatial functions")
            except pexExcept.Exception:
                pass

        for numKernelParams in (1, 3):
            spFuncList = []
            for ii in range(numKernelParams):
                spFuncList.append(spFunc.clone())
            try:
                afwMath.LinearCombinationKernel(kernelList, spFuncList)
                self.fail(
                    "Should have failed with wrong # of spatial functions")
            except pexExcept.Exception:
                pass
            kParamList = [0.2] * numKernelParams
            try:
                afwMath.LinearCombinationKernel(kernelList, kParamList)
                self.fail(
                    "Should have failed with wrong # of kernel parameters")
            except pexExcept.Exception:
                pass
            try:
                afwMath.SeparableKernel(kWidth, kHeight, gaussFunc1,
                                        gaussFunc1, spFuncList)
                self.fail(
                    "Should have failed with wrong # of spatial functions")
            except pexExcept.Exception:
                pass

        for pointX in range(-1, kWidth + 2):
            for pointY in range(-1, kHeight + 2):
                if (0 <= pointX < kWidth) and (0 <= pointY < kHeight):
                    continue
                try:
                    afwMath.DeltaFunctionKernel(
                        kWidth, kHeight, lsst.geom.Point2I(pointX, pointY))
                    self.fail("Should have failed with point not on kernel")
                except pexExcept.Exception:
                    pass
    def convolveImage(self, maskedImage, psf, doSmooth=True):
        """Convolve the image with the PSF

        We convolve the image with a Gaussian approximation to the PSF,
        because this is separable and therefore fast. It's technically a
        correlation rather than a convolution, but since we use a symmetric
        Gaussian there's no difference.

        The convolution can be disabled with ``doSmooth=False``. If we do
        convolve, we mask the edges as ``EDGE`` and return the convolved image
        with the edges removed. This is because we can't convolve the edges
        because the kernel would extend off the image.

        Parameters
        ----------
        maskedImage : `lsst.afw.image.MaskedImage`
            Image to convolve.
        psf : `lsst.afw.detection.Psf`
            PSF to convolve with (actually with a Gaussian approximation
            to it).
        doSmooth : `bool`
            Actually do the convolution? Set to False when running on
            e.g. a pre-convolved image, or a mask plane.

        Return Struct contents
        ----------------------
        middle : `lsst.afw.image.MaskedImage`
            Convolved image, without the edges.
        sigma : `float`
            Gaussian sigma used for the convolution.
        """
        self.metadata.set("doSmooth", doSmooth)
        sigma = psf.computeShape().getDeterminantRadius()
        self.metadata.set("sigma", sigma)

        if not doSmooth:
            middle = maskedImage.Factory(maskedImage)
            return pipeBase.Struct(middle=middle, sigma=sigma)

        # Smooth using a Gaussian (which is separable, hence fast) of width sigma
        # Make a SingleGaussian (separable) kernel with the 'sigma'
        kWidth = self.calculateKernelSize(sigma)
        self.metadata.set("smoothingKernelWidth", kWidth)
        gaussFunc = afwMath.GaussianFunction1D(sigma)
        gaussKernel = afwMath.SeparableKernel(kWidth, kWidth, gaussFunc,
                                              gaussFunc)

        convolvedImage = maskedImage.Factory(maskedImage.getBBox())

        afwMath.convolve(convolvedImage, maskedImage, gaussKernel,
                         afwMath.ConvolutionControl())
        #
        # Only search psf-smoothed part of frame
        #
        goodBBox = gaussKernel.shrinkBBox(convolvedImage.getBBox())
        middle = convolvedImage.Factory(convolvedImage, goodBBox,
                                        afwImage.PARENT, False)
        #
        # Mark the parts of the image outside goodBBox as EDGE
        #
        self.setEdgeBits(maskedImage, goodBBox,
                         maskedImage.getMask().getPlaneBitMask("EDGE"))

        return pipeBase.Struct(middle=middle, sigma=sigma)