def makeTest2(doAddNoise, shiftX=5, shiftY=3): gaussian1 = afwMath.GaussianFunction2D(1., 1., 0.) kernel1 = afwMath.AnalyticKernel(imSize, imSize, gaussian1) image1 = afwImage.ImageD(kernel1.getDimensions()) kernel1.computeImage(image1, False) image1 *= 10000 image1 = image1.convertF() #### boxA = afwGeom.Box2I(afwGeom.PointI(imSize // 2, imSize // 2), afwGeom.ExtentI(imSize // 2, imSize // 2)) boxB = afwGeom.Box2I( afwGeom.PointI(imSize // 2 - shiftX, imSize // 2 - shiftY), afwGeom.ExtentI(imSize // 2, imSize // 2)) subregA = afwImage.ImageF(image1, boxA, afwImage.PARENT) subregB = afwImage.ImageF(image1, boxB, afwImage.PARENT, True) subregA += subregB ### mask1 = afwImage.MaskU(kernel1.getDimensions()) var1 = afwImage.ImageF(image1, True) mi1 = afwImage.MaskedImageF(image1, mask1, var1) if doAddNoise: addNoise(mi1) gaussian2 = afwMath.GaussianFunction2D(2., 1.5, 0.5 * num.pi) kernel2 = afwMath.AnalyticKernel(imSize, imSize, gaussian2) image2 = afwImage.ImageD(kernel2.getDimensions()) kernel2.computeImage(image2, False) image2 *= 10000 image2 = image2.convertF() mask2 = afwImage.MaskU(kernel2.getDimensions()) var2 = afwImage.ImageF(image2, True) mi2 = afwImage.MaskedImageF(image2, mask2, var2) if doAddNoise: addNoise(mi2) return mi1, mi2
def makeSpatialKernel(self, order): basicGaussian1 = afwMath.GaussianFunction2D(2., 2., 0.) basicKernel1 = afwMath.AnalyticKernel(self.ksize, self.ksize, basicGaussian1) basicGaussian2 = afwMath.GaussianFunction2D(5., 3., 0.5 * num.pi) basicKernel2 = afwMath.AnalyticKernel(self.ksize, self.ksize, basicGaussian2) basisList = [] basisList.append(basicKernel1) basisList.append(basicKernel2) basisList = ipDiffim.renormalizeKernelList(basisList) spatialKernelFunction = afwMath.PolynomialFunction2D(order) spatialKernel = afwMath.LinearCombinationKernel( basisList, spatialKernelFunction) kCoeffs = [ [ 0.0 for x in range(1, spatialKernelFunction.getNParameters() + 1) ], [ 0.01 * x for x in range(1, spatialKernelFunction.getNParameters() + 1) ] ] kCoeffs[0][ 0] = 1.0 # it does not vary spatially; constant across image spatialKernel.setSpatialParameters(kCoeffs) return spatialKernel
def makeTest1(doAddNoise): gaussian1 = afwMath.GaussianFunction2D(1., 1., 0.) kernel1 = afwMath.AnalyticKernel(imSize, imSize, gaussian1) image1 = afwImage.ImageD(kernel1.getDimensions()) kernel1.computeImage(image1, False) image1 *= 10000 image1 = image1.convertF() mask1 = afwImage.Mask(kernel1.getDimensions()) var1 = afwImage.ImageF(image1, True) mi1 = afwImage.MaskedImageF(image1, mask1, var1) if doAddNoise: addNoise(mi1) gaussian2 = afwMath.GaussianFunction2D(2., 1.5, 0.5 * num.pi) kernel2 = afwMath.AnalyticKernel(imSize, imSize, gaussian2) image2 = afwImage.ImageD(kernel2.getDimensions()) kernel2.computeImage(image2, False) image2 *= 10000 image2 = image2.convertF() mask2 = afwImage.Mask(kernel2.getDimensions()) var2 = afwImage.ImageF(image2, True) mi2 = afwImage.MaskedImageF(image2, mask2, var2) if doAddNoise: addNoise(mi2) return mi1, mi2
def makeTest1(doAddNoise): gaussian1 = afwMath.GaussianFunction2D(1.*gScale, 1.*gScale, 0.) kernel1 = afwMath.AnalyticKernel(imSize, imSize, gaussian1) image1 = afwImage.ImageD(kernel1.getDimensions()) kernel1.computeImage(image1, doNorm) image1 *= scaling # total counts = scaling image1 = image1.convertF() mask1 = afwImage.Mask(kernel1.getDimensions()) var1 = afwImage.ImageF(image1, True) mi1 = afwImage.MaskedImageF(image1, mask1, var1) if doAddNoise: addNoise(mi1) gaussian2 = afwMath.GaussianFunction2D(2.*gScale, 1.5*gScale, 0.5*np.pi) kernel2 = afwMath.AnalyticKernel(imSize, imSize, gaussian2) image2 = afwImage.ImageD(kernel2.getDimensions()) kernel2.computeImage(image2, doNorm) image2 *= scaling # total counts = scaling image2 = image2.convertF() mask2 = afwImage.Mask(kernel2.getDimensions()) var2 = afwImage.ImageF(image2, True) mi2 = afwImage.MaskedImageF(image2, mask2, var2) if doAddNoise: addNoise(mi2) return mi1, mi2
def testUnityConvolution(self): """Verify that convolution with a centered delta function reproduces the original. """ # create a delta function kernel that has 1,1 in the center kFunc = afwMath.IntegerDeltaFunction2D(0.0, 0.0) kernel = afwMath.AnalyticKernel(3, 3, kFunc) doNormalize = False doCopyEdge = False afwMath.convolve(self.cnvImage, self.maskedImage.getImage(), kernel, doNormalize, doCopyEdge) cnvImArr = self.cnvImage.getArray() afwMath.convolve(self.cnvMaskedImage, self.maskedImage, kernel, doNormalize, doCopyEdge) cnvImMaskVarArr = self.cnvMaskedImage.getArrays() refCnvImMaskVarArr = self.maskedImage.getArrays() skipMaskArr = numpy.isnan(cnvImMaskVarArr[0]) kernelDescr = "Centered DeltaFunctionKernel (testing unity convolution)" errStr = imTestUtils.imagesDiffer(cnvImArr, refCnvImMaskVarArr[0], skipMaskArr=skipMaskArr) if errStr: self.fail("convolve(Image, kernel=%s, doNormalize=%s, doCopyEdge=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, errStr)) errStr = imTestUtils.maskedImagesDiffer(cnvImMaskVarArr, refCnvImMaskVarArr, skipMaskArr=skipMaskArr) if errStr: self.fail("convolve(MaskedImage, kernel=%s, doNormalize=%s, doCopyEdge=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, errStr)) self.assert_(sameMaskPlaneDicts(self.cnvMaskedImage, self.maskedImage), "convolve(MaskedImage, kernel=%s, doNormalize=%s, doCopyEdge=%s) failed:\n%s" % \ (kernelDescr, doNormalize, doCopyEdge, "convolved mask dictionary does not match input"))
def testUnityConvolution(self): """Verify that convolution with a centered delta function reproduces the original. """ # create a delta function kernel that has 1,1 in the center kFunc = afwMath.IntegerDeltaFunction2D(0.0, 0.0) kernel = afwMath.AnalyticKernel(3, 3, kFunc) doNormalize = False doCopyEdge = False afwMath.convolve(self.cnvImage, self.maskedImage.getImage(), kernel, doNormalize, doCopyEdge) afwMath.convolve(self.cnvMaskedImage, self.maskedImage, kernel, doNormalize, doCopyEdge) cnvImMaskVarArr = self.cnvMaskedImage.getArrays() skipMaskArr = numpy.array(numpy.isnan(cnvImMaskVarArr[0]), dtype=numpy.uint16) kernelDescr = "Centered DeltaFunctionKernel (testing unity convolution)" self.assertImagesAlmostEqual(self.cnvImage, self.maskedImage.getImage(), skipMask=skipMaskArr, msg=kernelDescr) self.assertMaskedImagesAlmostEqual(self.cnvMaskedImage, self.maskedImage, skipMask=skipMaskArr, msg=kernelDescr)
def testAnalyticKernel(self): """Test AnalyticKernel using a Gaussian function """ kWidth = 5 kHeight = 8 gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) k = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc) fArr = np.zeros(shape=[k.getWidth(), k.getHeight()], dtype=float) for xsigma in (0.1, 1.0, 3.0): for ysigma in (0.1, 1.0, 3.0): for angle in (0.0, 0.4, 1.1): gaussFunc.setParameters((xsigma, ysigma, angle)) # compute array of function values and normalize for row in range(k.getHeight()): y = row - k.getCtrY() for col in range(k.getWidth()): x = col - k.getCtrX() fArr[col, row] = gaussFunc(x, y) fArr /= fArr.sum() k.setKernelParameters((xsigma, ysigma, angle)) with lsst.utils.tests.getTempFilePath(".fits") as filename: k.writeFits(filename) k2 = afwMath.AnalyticKernel.readFits(filename) self.kernelCheck(k, k2) kImage = afwImage.ImageD(k2.getDimensions()) k2.computeImage(kImage, True) kArr = kImage.getArray().transpose() if not np.allclose(fArr, kArr): self.fail("%s = %s != %s for xsigma=%s, ysigma=%s" % (k2.__class__.__name__, kArr, fArr, xsigma, ysigma))
def testSetCtr(self): """Test setCtrCol/Row""" kWidth = 3 kHeight = 4 pol = pexPolicy.Policy() additionalData = dafBase.PropertySet() loc = dafPersist.LogicalLocation( os.path.join(testPath, "data", "kernel7.boost")) persistence = dafPersist.Persistence.getPersistence(pol) gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) k = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc) for xCtr in range(kWidth): k.setCtrX(xCtr) for yCtr in range(kHeight): k.setCtrY(yCtr) storageList = dafPersist.StorageList() storage = persistence.getPersistStorage("XmlStorage", loc) storageList.append(storage) persistence.persist(k, storageList, additionalData) storageList2 = dafPersist.StorageList() storage2 = persistence.getRetrieveStorage("XmlStorage", loc) storageList2.append(storage2) k2 = persistence.unsafeRetrieve("AnalyticKernel", storageList2, additionalData) self.kernelCheck(k, k2) self.assertEqual(k2.getCtrX(), xCtr) self.assertEqual(k2.getCtrY(), yCtr)
def testSpatiallyVaryingAnalyticConvolve(self): """Test in-place convolution with a spatially varying AnalyticKernel """ kWidth = 7 kHeight = 6 # create spatial model sFunc = afwMath.PolynomialFunction2D(1) minSigma = 1.5 maxSigma = 1.501 # spatial parameters are a list of entries, one per kernel parameter; # each entry is a list of spatial parameters sParams = ( (minSigma, (maxSigma - minSigma) / self.width, 0.0), (minSigma, 0.0, (maxSigma - minSigma) / self.height), (0.0, 0.0, 0.0), ) kFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) kernel = afwMath.AnalyticKernel(kWidth, kHeight, kFunc, sFunc) kernel.setSpatialParameters(sParams) for maxInterpDist, rtol, methodStr in ( (0, 1.0e-5, "brute force"), (10, 1.0e-5, "interpolation over 10 x 10 pixels"), ): self.runStdTest( kernel, kernelDescr= "Spatially Varying Gaussian Analytic Kernel using %s" % (methodStr, ), maxInterpDist=maxInterpDist, rtol=rtol)
def testSpatiallyVaryingSeparableConvolve(self): """Test convolution with a spatially varying SeparableKernel """ kWidth = 7 kHeight = 6 # create spatial model sFunc = afwMath.PolynomialFunction2D(1) minSigma = 0.1 maxSigma = 3.0 # spatial parameters are a list of entries, one per kernel parameter; # each entry is a list of spatial parameters sParams = ( (minSigma, (maxSigma - minSigma) / self.width, 0.0), (minSigma, 0.0, (maxSigma - minSigma) / self.height), (0.0, 0.0, 0.0), ) gaussFunc1 = afwMath.GaussianFunction1D(1.0) gaussFunc2 = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) separableKernel = afwMath.SeparableKernel(kWidth, kHeight, gaussFunc1, gaussFunc1, sFunc) analyticKernel = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc2, sFunc) separableKernel.setSpatialParameters(sParams[0:2]) analyticKernel.setSpatialParameters(sParams) self.runStdTest( separableKernel, refKernel=analyticKernel, kernelDescr="Spatially Varying Gaussian Separable Kernel")
def testKernelPsf(self): """Test creating a Psf from a Kernel""" x,y = 10.4999, 10.4999 ksize = 15 sigma1 = 1 # # Make a PSF from that kernel # kPsf = measAlg.KernelPsf(afwMath.AnalyticKernel(ksize, ksize, afwMath.GaussianFunction2D(sigma1, sigma1))) kIm = kPsf.computeImage(afwGeom.Point2D(x, y)) # # And now via the dgPsf model # dgPsf = measAlg.DoubleGaussianPsf(ksize, ksize, sigma1) dgIm = dgPsf.computeImage(afwGeom.Point2D(x, y)) # # Check that they're the same # diff = type(kIm)(kIm, True); diff -= dgIm stats = afwMath.makeStatistics(diff, afwMath.MAX | afwMath.MIN) self.assertAlmostEqual(stats.getValue(afwMath.MAX), 0.0, places=16) self.assertAlmostEqual(stats.getValue(afwMath.MIN), 0.0, places=16) if display: mos = displayUtils.Mosaic() mos.setBackground(-0.1) ds9.mtv(mos.makeMosaic([kIm, dgIm, diff], mode="x"), frame=1)
def _computeVaryingPsf(self): """Compute a varying PSF as a linear combination of PCA (== Karhunen-Loeve) basis functions We simply desire a PSF that is not constant across the image, so the precise choice of parameters (e.g., sigmas, setSpatialParameters) are not crucial. """ kernelSize = 31 sigma1 = 1.75 sigma2 = 2.0 * sigma1 basisKernelList = [] for sigma in (sigma1, sigma2): basisKernel = afwMath.AnalyticKernel( kernelSize, kernelSize, afwMath.GaussianFunction2D(sigma, sigma)) basisImage = afwImage.ImageD(basisKernel.getDimensions()) basisKernel.computeImage(basisImage, True) basisImage /= np.sum(basisImage.getArray()) if sigma == sigma1: basisImage0 = basisImage else: basisImage -= basisImage0 basisKernelList.append(afwMath.FixedKernel(basisImage)) order = 1 spFunc = afwMath.PolynomialFunction2D(order) exactKernel = afwMath.LinearCombinationKernel(basisKernelList, spFunc) exactKernel.setSpatialParameters([[1.0, 0, 0], [0.0, 0.5E-2, 0.2E-2]]) exactPsf = measAlg.PcaPsf(exactKernel) return exactPsf
def setUp(self): self.config = ipDiffim.ImagePsfMatchTask.ConfigClass() self.subconfig = self.config.kernel.active self.policy = pexConfig.makePolicy(self.subconfig) self.kSize = self.policy.getInt('kernelSize') # gaussian reference kernel self.gSize = self.kSize self.gaussFunction = afwMath.GaussianFunction2D(2, 3) self.gaussKernel = afwMath.AnalyticKernel(self.gSize, self.gSize, self.gaussFunction) # known input images try: self.defDataDir = lsst.utils.getPackageDir('afwdata') except Exception: self.defDataDir = None if self.defDataDir: defImagePath = os.path.join(self.defDataDir, "DC3a-Sim", "sci", "v5-e0", "v5-e0-c011-a00.sci.fits") self.templateImage = afwImage.MaskedImageF(defImagePath) self.scienceImage = self.templateImage.Factory( self.templateImage.getDimensions()) afwMath.convolve(self.scienceImage, self.templateImage, self.gaussKernel, False)
def makeKernel(self): kCols = 7 kRows = 6 # create spatial model sFunc = afwMath.PolynomialFunction2D(1) minSigma = 0.1 maxSigma = 3.0 # spatial parameters are a list of entries, one per kernel parameter; # each entry is a list of spatial parameters xSlope = (maxSigma - minSigma) / self.bbox.getWidth() ySlope = (maxSigma - minSigma) / self.bbox.getHeight() xOrigin = minSigma - (self.xy0[0] * xSlope) yOrigin = minSigma - (self.xy0[1] * ySlope) sParams = ( (xOrigin, xSlope, 0.0), (yOrigin, 0.0, ySlope), (0.0, 0.0, 0.0), ) kFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) kernel = afwMath.AnalyticKernel(kCols, kRows, kFunc, sFunc) kernel.setSpatialParameters(sParams) return kernel
def testGaussianWithNoise(self): # Convolve a real image with a gaussian and try and recover # it. Add noise and perform the same test. gsize = self.ps["kernelSize"] gaussFunction = afwMath.GaussianFunction2D(2, 3) gaussKernel = afwMath.AnalyticKernel(gsize, gsize, gaussFunction) kImageIn = afwImage.ImageD(geom.Extent2I(gsize, gsize)) kSumIn = gaussKernel.computeImage(kImageIn, False) imX, imY = self.templateExposure2.getMaskedImage().getDimensions() smi = afwImage.MaskedImageF(geom.Extent2I(imX, imY)) afwMath.convolve(smi, self.templateExposure2.getMaskedImage(), gaussKernel, False) bbox = gaussKernel.shrinkBBox(smi.getBBox(afwImage.LOCAL)) tmi2 = afwImage.MaskedImageF(self.templateExposure2.getMaskedImage(), bbox, origin=afwImage.LOCAL) smi2 = afwImage.MaskedImageF(smi, bbox, origin=afwImage.LOCAL) kc = ipDiffim.KernelCandidateF(self.x02, self.y02, tmi2, smi2, self.ps) kList = ipDiffim.makeKernelBasisList(self.subconfig) kc.build(kList) self.assertEqual(kc.isInitialized(), True) kImageOut = kc.getImage() soln = kc.getKernelSolution(ipDiffim.KernelCandidateF.RECENT) self.assertAlmostEqual(soln.getKsum(), kSumIn) # 8.7499380640430563e-06 != 0.0 within 7 places self.assertAlmostEqual(soln.getBackground(), 0.0, 4) for j in range(kImageOut.getHeight()): for i in range(kImageOut.getWidth()): # in the outskirts of the kernel, the ratio can get screwed because of low S/N # e.g. 7.45817359824e-09 vs. 1.18062529402e-08 # in the guts of the kernel it should look closer if kImageIn[i, j, afwImage.LOCAL] > 1e-4: # sigh, too bad this sort of thing fails.. # 0.99941584433815966 != 1.0 within 3 places self.assertAlmostEqual(kImageOut[i, j, afwImage.LOCAL]/kImageIn[i, j, afwImage.LOCAL], 1.0, 2) # now repeat with noise added; decrease precision of comparison self.addNoise(smi2) kc = ipDiffim.KernelCandidateF(self.x02, self.y02, tmi2, smi2, self.ps) kList = ipDiffim.makeKernelBasisList(self.subconfig) kc.build(kList) self.assertEqual(kc.isInitialized(), True) kImageOut = kc.getImage() soln = kc.getKernelSolution(ipDiffim.KernelCandidateF.RECENT) self.assertAlmostEqual(soln.getKsum(), kSumIn, 3) if not self.ps.get("fitForBackground"): self.assertEqual(soln.getBackground(), 0.0) for j in range(kImageOut.getHeight()): for i in range(kImageOut.getWidth()): if kImageIn[i, j, afwImage.LOCAL] > 1e-2: self.assertAlmostEqual(kImageOut[i, j, afwImage.LOCAL], kImageIn[i, j, afwImage.LOCAL], 2)
def main(): gaussFunction = afwMath.GaussianFunction2D(3, 2, 0.5) gaussKernel = afwMath.AnalyticKernel(10, 10, gaussFunction) inImage = afwImage.ImageF(afwGeom.Extent2I(100, 100)) inImage.set(1) if disp: ds9.mtv(inImage, frame = 0) # works outImage = afwImage.ImageF(afwGeom.Extent2I(100, 100)) afwMath.convolve(outImage, inImage, gaussKernel, False, True) if disp: ds9.mtv(outImage, frame = 1) print("Should be a number: ", afwMath.makeStatistics( outImage, afwMath.MEAN).getValue()) print("Should be a number: ", afwMath.makeStatistics( outImage, afwMath.STDEV).getValue()) # not works ... now does work outImage = afwImage.ImageF(afwGeom.Extent2I(100, 100)) afwMath.convolve(outImage, inImage, gaussKernel, False, False) if disp: ds9.mtv(outImage, frame = 2) print("Should be a number: ", afwMath.makeStatistics( outImage, afwMath.MEAN).getValue()) print("Should be a number: ", afwMath.makeStatistics( outImage, afwMath.STDEV).getValue()) # This will print nan sctrl = afwMath.StatisticsControl() sctrl.setNanSafe(False) print ("Should be a nan (nanSafe set to False): " + str(afwMath.makeStatistics(outImage, afwMath.MEAN, sctrl).getValue()))
def testLinearCombinationKernelAnalytic(self): """Test LinearCombinationKernel using analytic basis kernels. The basis kernels are mutable so that we can verify that the LinearCombinationKernel has private copies of the basis kernels. """ kWidth = 5 kHeight = 8 # create list of kernels basisImArrList = [] basisKernelList = [] for basisKernelParams in [(1.2, 0.3, 1.570796), (1.0, 0.2, 0.0)]: basisKernelFunction = afwMath.GaussianFunction2D( *basisKernelParams) basisKernel = afwMath.AnalyticKernel( kWidth, kHeight, basisKernelFunction) basisImage = afwImage.ImageD(basisKernel.getDimensions()) basisKernel.computeImage(basisImage, True) basisImArrList.append(basisImage.getArray()) basisKernelList.append(basisKernel) kParams = [0.0]*len(basisKernelList) kernel = afwMath.LinearCombinationKernel(basisKernelList, kParams) self.assertTrue(not kernel.isDeltaFunctionBasis()) self.basicTests(kernel, len(kParams)) kernelResized = self.verifyResized(kernel) self.basicTests(kernelResized, len(kParams)) # make sure the linear combination kernel has private copies of its basis kernels # by altering the local basis kernels and making sure the new images do # NOT match modBasisImArrList = [] for basisKernel in basisKernelList: basisKernel.setKernelParameters((0.4, 0.5, 0.6)) modBasisImage = afwImage.ImageD(basisKernel.getDimensions()) basisKernel.computeImage(modBasisImage, True) modBasisImArrList.append(modBasisImage.getArray()) for ii in range(len(basisKernelList)): kParams = [0.0]*len(basisKernelList) kParams[ii] = 1.0 kernel.setKernelParameters(kParams) kIm = afwImage.ImageD(kernel.getDimensions()) kernel.computeImage(kIm, True) kImArr = kIm.getArray() if not np.allclose(kImArr, basisImArrList[ii]): self.fail(f"{kernel.__class__.__name__} = {kImArr} != " f"{basisImArrList[ii]} for the {ii}'th basis kernel") if np.allclose(kImArr, modBasisImArrList[ii]): self.fail(f"{kernel.__class__.__name__} = {kImArr} != " f"{modBasisImArrList[ii]} for *modified* {ii}'th basis kernel") kernelClone = kernel.clone() errStr = self.compareKernels(kernel, kernelClone) if errStr: self.fail(errStr) self.verifyCache(kernel, hasCache=False)
def testSVAnalyticKernel(self): """Test spatially varying AnalyticKernel using a Gaussian function Just tests cloning. """ kWidth = 5 kHeight = 8 # spatial model spFunc = afwMath.PolynomialFunction2D(1) # spatial parameters are a list of entries, one per kernel parameter; # each entry is a list of spatial parameters sParams = ( (1.0, 1.0, 0.0), (1.0, 0.0, 1.0), (0.5, 0.5, 0.5), ) gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) kernel = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc, spFunc) kernel.setSpatialParameters(sParams) kernelClone = kernel.clone() errStr = self.compareKernels(kernel, kernelClone) if errStr: self.fail(errStr) newSParams = ( (0.1, 0.2, 0.5), (0.1, 0.5, 0.2), (0.2, 0.3, 0.3), ) kernel.setSpatialParameters(newSParams) errStr = self.compareKernels(kernel, kernelClone) if not errStr: self.fail( "Clone was modified by changing original's spatial parameters") # # check that we can construct a FixedKernel from a LinearCombinationKernel # x, y = 100, 200 kernel2 = afwMath.FixedKernel(kernel, lsst.geom.PointD(x, y)) self.assertTrue(re.search("AnalyticKernel", kernel.toString())) self.assertFalse(kernel2.isSpatiallyVarying()) self.assertTrue(re.search("FixedKernel", kernel2.toString())) self.assertTrue(kernel.isSpatiallyVarying()) kim = afwImage.ImageD(kernel.getDimensions()) kernel.computeImage(kim, True, x, y) kim2 = afwImage.ImageD(kernel2.getDimensions()) kernel2.computeImage(kim2, True) assert_allclose(kim.getArray(), kim2.getArray())
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 testSpatiallyInvariantConvolve(self): """Test convolution with a spatially invariant Gaussian function """ kWidth = 6 kHeight = 7 kFunc = afwMath.GaussianFunction2D(2.5, 1.5, 0.5) kernel = afwMath.AnalyticKernel(kWidth, kHeight, kFunc) self.runStdTest(kernel, kernelDescr="Gaussian Analytic Kernel")
def testGaussian(self, imsize=50): # Convolve a delta function with a known gaussian; try to # recover using delta-function basis gsize = self.ps["kernelSize"] tsize = imsize + gsize gaussFunction = afwMath.GaussianFunction2D(2, 3) gaussKernel = afwMath.AnalyticKernel(gsize, gsize, gaussFunction) kImageIn = afwImage.ImageD(geom.Extent2I(gsize, gsize)) gaussKernel.computeImage(kImageIn, False) # template image with a single hot pixel in the exact center tmi = afwImage.MaskedImageF(geom.Extent2I(tsize, tsize)) tmi.set(0, 0x0, 1e-4) cpix = tsize // 2 tmi[cpix, cpix, afwImage.LOCAL] = (1, 0x0, 1) # science image smi = afwImage.MaskedImageF(tmi.getDimensions()) convolutionControl = afwMath.ConvolutionControl() convolutionControl.setDoNormalize(False) afwMath.convolve(smi, tmi, gaussKernel, convolutionControl) # get the actual kernel sum (since the image is not infinite) gscaling = afwMath.makeStatistics(smi, afwMath.SUM).getValue(afwMath.SUM) # grab only the non-masked subregion bbox = gaussKernel.shrinkBBox(smi.getBBox(afwImage.LOCAL)) tmi2 = afwImage.MaskedImageF(tmi, bbox, origin=afwImage.LOCAL) smi2 = afwImage.MaskedImageF(smi, bbox, origin=afwImage.LOCAL) # make sure its a valid subregion! for j in range(tmi2.getHeight()): for i in range(tmi2.getWidth()): self.assertEqual(tmi2.mask[i, j, afwImage.LOCAL], 0) self.assertEqual(smi2.mask[i, j, afwImage.LOCAL], 0) kc = ipDiffim.KernelCandidateF(0.0, 0.0, tmi2, smi2, self.ps) kList = ipDiffim.makeKernelBasisList(self.subconfig) kc.build(kList) self.assertEqual(kc.isInitialized(), True) kImageOut = kc.getImage() soln = kc.getKernelSolution(ipDiffim.KernelCandidateF.RECENT) self.assertAlmostEqual(soln.getKsum(), gscaling) self.assertAlmostEqual(soln.getBackground(), 0.0) for j in range(kImageOut.getHeight()): for i in range(kImageOut.getWidth()): self.assertAlmostEqual( kImageOut[i, j, afwImage.LOCAL] / kImageIn[i, j, afwImage.LOCAL], 1.0, 5)
def testSetCtr(self): """Test setCtrCol/Row""" kWidth = 3 kHeight = 4 gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) kernel = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc) for xCtr in range(kWidth): for yCtr in range(kHeight): center = lsst.geom.Point2I(xCtr, yCtr) kernel.setCtr(center) self.assertEqual(kernel.getCtr(), center)
def makeTest3(doAddNoise): gaussian1 = afwMath.GaussianFunction2D(1. * gScale, 1. * gScale, 0.) kernel1 = afwMath.AnalyticKernel(imSize, imSize, gaussian1) image1 = afwImage.ImageD(kernel1.getDimensions()) kernel1.computeImage(image1, doNorm) image1 *= scaling # total counts = scaling image1 = image1.convertF() mask1 = afwImage.MaskU(kernel1.getDimensions()) var1 = afwImage.ImageF(image1, True) mi1 = afwImage.MaskedImageF(image1, mask1, var1) gaussian2 = afwMath.GaussianFunction2D(2. * gScale, 1.5 * gScale, 0.5 * num.pi) kernel2 = afwMath.AnalyticKernel(imSize, imSize, gaussian2) image2 = afwImage.ImageD(kernel2.getDimensions()) kernel2.computeImage(image2, doNorm) image2 *= scaling # total counts = scaling image2 = image2.convertF() mask2 = afwImage.MaskU(kernel2.getDimensions()) var2 = afwImage.ImageF(image2, True) mi2 = afwImage.MaskedImageF(image2, mask2, var2) image3 = afwImage.ImageF(image1, True) for y in range(imSize): for x in range(imSize // 2): image3.set(x, y, image2.get(x, y)) counts = afwMath.makeStatistics(image3, afwMath.SUM).getValue() image3 /= counts image3 *= scaling mask3 = afwImage.MaskU(image3.getDimensions()) var3 = afwImage.ImageF(image3, True) mi3 = afwImage.MaskedImageF(image3, mask3, var3) if doAddNoise: addNoise(mi1) addNoise(mi2) addNoise(mi3) return mi1, mi2, mi3
def testAnalyticKernel(self): """Test AnalyticKernel using a Gaussian function """ kWidth = 5 kHeight = 8 pol = pexPolicy.Policy() additionalData = dafBase.PropertySet() loc = dafPersist.LogicalLocation( os.path.join(testPath, "data", "kernel2.boost")) persistence = dafPersist.Persistence.getPersistence(pol) gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) k = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc) fArr = np.zeros(shape=[k.getWidth(), k.getHeight()], dtype=float) for xsigma in (0.1, 1.0, 3.0): for ysigma in (0.1, 1.0, 3.0): for angle in (0.0, 0.4, 1.1): gaussFunc.setParameters((xsigma, ysigma, angle)) # compute array of function values and normalize for row in range(k.getHeight()): y = row - k.getCtrY() for col in range(k.getWidth()): x = col - k.getCtrX() fArr[col, row] = gaussFunc(x, y) fArr /= fArr.sum() k.setKernelParameters((xsigma, ysigma, angle)) storageList = dafPersist.StorageList() storage = persistence.getPersistStorage("XmlStorage", loc) storageList.append(storage) persistence.persist(k, storageList, additionalData) storageList2 = dafPersist.StorageList() storage2 = persistence.getRetrieveStorage( "XmlStorage", loc) storageList2.append(storage2) x = persistence.unsafeRetrieve("AnalyticKernel", storageList2, additionalData) k2 = afwMath.AnalyticKernel.swigConvert(x) self.kernelCheck(k, k2) kImage = afwImage.ImageD(k2.getDimensions()) k2.computeImage(kImage, True) kArr = kImage.getArray().transpose() if not np.allclose(fArr, kArr): self.fail("%s = %s != %s for xsigma=%s, ysigma=%s" % (k2.__class__.__name__, kArr, fArr, xsigma, ysigma))
def makeTest2(doAddNoise, shiftX=int(2.0 * gScale), shiftY=int(1.0 * gScale)): gaussian1 = afwMath.GaussianFunction2D(1. * gScale, 1. * gScale, 0.) kernel1 = afwMath.AnalyticKernel(imSize, imSize, gaussian1) image1 = afwImage.ImageD(kernel1.getDimensions()) kernel1.computeImage(image1, doNorm) image1 = image1.convertF() #### boxA = afwGeom.Box2I(afwGeom.PointI(0, 0), afwGeom.ExtentI(imSize - shiftX, imSize - shiftY)) boxB = afwGeom.Box2I(afwGeom.PointI(shiftX, shiftY), afwGeom.ExtentI(imSize - shiftX, imSize - shiftY)) subregA = afwImage.ImageF(image1, boxA, afwImage.LOCAL) subregB = afwImage.ImageF(image1, boxB, afwImage.LOCAL, True) subregA += subregB # this messes up the total counts so rescale counts = afwMath.makeStatistics(image1, afwMath.SUM).getValue() image1 /= counts image1 *= scaling ### mask1 = afwImage.Mask(kernel1.getDimensions()) var1 = afwImage.ImageF(image1, True) mi1 = afwImage.MaskedImageF(image1, mask1, var1) if doAddNoise: addNoise(mi1) gaussian2 = afwMath.GaussianFunction2D(2. * gScale, 1.5 * gScale, 0.5 * np.pi) kernel2 = afwMath.AnalyticKernel(imSize, imSize, gaussian2) image2 = afwImage.ImageD(kernel2.getDimensions()) kernel2.computeImage(image2, doNorm) image2 *= scaling # total counts = scaling image2 = image2.convertF() mask2 = afwImage.Mask(kernel2.getDimensions()) var2 = afwImage.ImageF(image2, True) mi2 = afwImage.MaskedImageF(image2, mask2, var2) if doAddNoise: addNoise(mi2) return mi1, mi2
def testSetCtr(self): """Test setCtrCol/Row""" kWidth = 3 kHeight = 4 gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) kernel = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc) for xCtr in range(kWidth): kernel.setCtrX(xCtr) for yCtr in range(kHeight): kernel.setCtrY(yCtr) self.assertEqual(kernel.getCtrX(), xCtr) self.assertEqual(kernel.getCtrY(), yCtr)
def testFixedKernelConvolve(self): """Test convolve with a fixed kernel """ kWidth = 6 kHeight = 7 kFunc = afwMath.GaussianFunction2D(2.5, 1.5, 0.5) analyticKernel = afwMath.AnalyticKernel(kWidth, kHeight, kFunc) kernelImage = afwImage.ImageD(afwGeom.Extent2I(kWidth, kHeight)) analyticKernel.computeImage(kernelImage, False) fixedKernel = afwMath.FixedKernel(kernelImage) self.runStdTest(fixedKernel, kernelDescr="Gaussian FixedKernel")
def testRenormalize(self): # inputs gauss1 = afwMath.GaussianFunction2D(2, 2) gauss2 = afwMath.GaussianFunction2D(3, 4) gauss3 = afwMath.GaussianFunction2D(0.2, 0.25) gaussKernel1 = afwMath.AnalyticKernel(self.kSize, self.kSize, gauss1) gaussKernel2 = afwMath.AnalyticKernel(self.kSize, self.kSize, gauss2) gaussKernel3 = afwMath.AnalyticKernel(self.kSize, self.kSize, gauss3) kimage1 = afwImage.ImageD(gaussKernel1.getDimensions()) ksum1 = gaussKernel1.computeImage(kimage1, False) kimage2 = afwImage.ImageD(gaussKernel2.getDimensions()) ksum2 = gaussKernel2.computeImage(kimage2, False) kimage3 = afwImage.ImageD(gaussKernel3.getDimensions()) ksum3 = gaussKernel3.computeImage(kimage3, False) self.assertNotEqual(ksum1, 1.) self.assertNotEqual(ksum2, 1.) self.assertNotEqual(ksum3, 1.) # no constraints on first kernels norm self.assertNotEqual(num.sum(num.ravel(kimage2.getArray())**2), 1.) self.assertNotEqual(num.sum(num.ravel(kimage3.getArray())**2), 1.) basisListIn = [] basisListIn.append(gaussKernel1) basisListIn.append(gaussKernel2) basisListIn.append(gaussKernel3) # outputs basisListOut = ipDiffim.renormalizeKernelList(basisListIn) gaussKernel1 = basisListOut[0] gaussKernel2 = basisListOut[1] gaussKernel3 = basisListOut[2] ksum1 = gaussKernel1.computeImage(kimage1, False) ksum2 = gaussKernel2.computeImage(kimage2, False) ksum3 = gaussKernel3.computeImage(kimage3, False) self.assertAlmostEqual(ksum1, 1.) self.assertAlmostEqual(ksum2, 0.) self.assertAlmostEqual(ksum3, 0.) # no constraints on first kernels norm self.assertAlmostEqual(num.sum(num.ravel(kimage2.getArray())**2), 1.) self.assertAlmostEqual(num.sum(num.ravel(kimage3.getArray())**2), 1.)
def makeGaussianKernelList(kWidth, kHeight, gaussParamsList): """Create a list of gaussian kernels. This is useful for constructing a LinearCombinationKernel. Inputs: - kWidth, kHeight: width and height of kernel - gaussParamsList: a list of parameters for GaussianFunction2D (each a 3-tuple of floats) """ kVec = [] for majorSigma, minorSigma, angle in gaussParamsList: kFunc = afwMath.GaussianFunction2D(majorSigma, minorSigma, angle) kVec.append(afwMath.AnalyticKernel(kWidth, kHeight, kFunc)) return kVec
def createImageAndKernel(sigma, psfSize, image): function = afwMath.GaussianFunction2D(sigma, sigma) kernel = afwMath.AnalyticKernel(psfSize, psfSize, function) psf = measAlg.KernelPsf(kernel) cim = afwImage.ImageF(image.getDimensions()) afwMath.convolve(cim, image, kernel, True) # Trim off the border pixels bbox = kernel.shrinkBBox(cim.getBBox(afwImage.LOCAL)) cim = afwImage.ImageF(cim, bbox, afwImage.LOCAL) cim.setXY0(0, 0) return cim, psf