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 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 runConvolveAndSubtract2(self, bgOrder=0, xloc=408, yloc=580): imsize = int(5 * self.kSize) p0 = geom.Point2I(xloc - imsize // 2, yloc - imsize // 2) p1 = geom.Point2I(xloc + imsize // 2, yloc + imsize // 2) bbox = geom.Box2I(p0, p1) tmi = afwImage.MaskedImageF(self.templateImage, bbox, origin=afwImage.LOCAL) smi = afwImage.MaskedImageF(self.scienceImage, bbox, origin=afwImage.LOCAL) bgFunc = afwMath.PolynomialFunction2D( bgOrder) # coeffs are 0. by default diffIm = ipDiffim.convolveAndSubtract(tmi, smi, self.gaussKernel, bgFunc) bbox = self.gaussKernel.shrinkBBox( diffIm.getBBox(origin=afwImage.LOCAL)) diffIm2 = afwImage.MaskedImageF(diffIm, bbox, origin=afwImage.LOCAL) for j in range(diffIm2.getHeight()): for i in range(diffIm2.getWidth()): self.assertAlmostEqual(diffIm2.image[i, j, afwImage.LOCAL], 0., 4)
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 testGood(self): ti = afwImage.MaskedImageF(afwGeom.Extent2I(100, 100)) ti.getVariance().set(0.1) ti.set(50, 50, (1., 0x0, 1.)) sKernel = self.makeSpatialKernel(2) si = afwImage.MaskedImageF(ti.getDimensions()) afwMath.convolve(si, ti, sKernel, True) bbox = afwGeom.Box2I(afwGeom.Point2I(25, 25), afwGeom.Point2I(75, 75)) si = afwImage.MaskedImageF(si, bbox, origin=afwImage.LOCAL) ti = afwImage.MaskedImageF(ti, bbox, origin=afwImage.LOCAL) kc = ipDiffim.KernelCandidateF(50., 50., ti, si, self.policy) sBg = afwMath.PolynomialFunction2D(1) bgCoeffs = [0., 0., 0.] sBg.setParameters(bgCoeffs) # must be initialized bskv = ipDiffim.BuildSingleKernelVisitorF(self.kList, self.policy) bskv.processCandidate(kc) self.assertEqual(kc.isInitialized(), True) #ds9.mtv(kc.getTemplateMaskedImage(), frame=1) #ds9.mtv(kc.getScienceMaskedImage(), frame=2) #ds9.mtv(kc.getKernelImage(ipDiffim.KernelCandidateF.RECENT), frame=3) #ds9.mtv(kc.getDifferenceImage(ipDiffim.KernelCandidateF.RECENT), frame=4) askv = ipDiffim.AssessSpatialKernelVisitorF(sKernel, sBg, self.policy) askv.processCandidate(kc) self.assertEqual(askv.getNProcessed(), 1) self.assertEqual(askv.getNRejected(), 0) self.assertEqual(kc.getStatus(), afwMath.SpatialCellCandidate.GOOD)
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.imgVal1, self.varVal1 = 100.0, 10.0 self.imgVal2, self.varVal2 = 200.0, 15.0 self.mimage = afwImage.MaskedImageF(100, 200) self.mimage.image.set(self.imgVal1) # # Set center of mask to 0, with 2 pixel border set to EDGE # self.BAD = afwImage.Mask.getPlaneBitMask("BAD") self.EDGE = afwImage.Mask.getPlaneBitMask("EDGE") self.mimage.mask.set(self.EDGE) centre = afwImage.Mask( self.mimage.mask, lsst.geom.Box2I(lsst.geom.Point2I(2, 2), self.mimage.getDimensions() - lsst.geom.Extent2I(4)), afwImage.LOCAL) centre.set(0x0) # self.mimage.variance.set(self.varVal1) # # Second MaskedImage # self.mimage2 = afwImage.MaskedImageF(self.mimage.getDimensions()) self.mimage2.image.set(self.imgVal2) self.mimage2.variance.set(self.varVal2) # # a Function2 # self.function = afwMath.PolynomialFunction2D(2) self.function.setParameters( list(range(self.function.getNParameters())))
def testRefactorGaussianLinearCombinationKernel(self): """Test LinearCombinationKernel.refactor with Gaussian basis kernels """ kWidth = 4 kHeight = 3 for spOrder in (0, 1, 2): spFunc = afwMath.PolynomialFunction2D(spOrder) numSpParams = spFunc.getNParameters() gaussParamsList = [ (1.5, 1.5, 0.0), (2.5, 1.5, 0.0), (2.5, 1.5, math.pi / 2.0), ] gaussBasisKernelList = makeGaussianKernelList( kWidth, kHeight, gaussParamsList) kernel = afwMath.LinearCombinationKernel( gaussBasisKernelList, spFunc) numBasisKernels = kernel.getNKernelParameters() maxVal = 1.01 + ((numSpParams - 1) * 0.1) sParamList = [np.arange(kInd + 1.0, kInd + maxVal, 0.1) for kInd in range(numBasisKernels)] kernel.setSpatialParameters(sParamList) refKernel = kernel.refactor() self.assertTrue(refKernel) errStr = self.compareKernels( kernel, refKernel, compareParams=False) if errStr: self.fail(f"failed with {errStr} for spOrder={spOrder}, numSpParams={numSpParams}")
def testGood(self): ti = afwImage.MaskedImageF(geom.Extent2I(100, 100)) ti.getVariance().set(0.1) ti[50, 50, afwImage.LOCAL] = (1., 0x0, 1.) sKernel = self.makeSpatialKernel(2) si = afwImage.MaskedImageF(ti.getDimensions()) convolutionControl = afwMath.ConvolutionControl() convolutionControl.setDoNormalize(True) afwMath.convolve(si, ti, sKernel, convolutionControl) bbox = geom.Box2I(geom.Point2I(25, 25), geom.Point2I(75, 75)) si = afwImage.MaskedImageF(si, bbox, origin=afwImage.LOCAL) ti = afwImage.MaskedImageF(ti, bbox, origin=afwImage.LOCAL) kc = ipDiffim.KernelCandidateF(50., 50., ti, si, self.ps) sBg = afwMath.PolynomialFunction2D(1) bgCoeffs = [0., 0., 0.] sBg.setParameters(bgCoeffs) # must be initialized bskv = ipDiffim.BuildSingleKernelVisitorF(self.kList, self.ps) bskv.processCandidate(kc) self.assertEqual(kc.isInitialized(), True) askv = ipDiffim.AssessSpatialKernelVisitorF(sKernel, sBg, self.ps) askv.processCandidate(kc) self.assertEqual(askv.getNProcessed(), 1) self.assertEqual(askv.getNRejected(), 0) self.assertEqual(kc.getStatus(), afwMath.SpatialCellCandidate.GOOD)
def testRefactorDeltaLinearCombinationKernel(self): """Test LinearCombinationKernel.refactor with delta function basis kernels """ kWidth = 4 kHeight = 3 for spOrder in (0, 1, 2): spFunc = afwMath.PolynomialFunction2D(spOrder) numSpParams = spFunc.getNParameters() basisKernelList = makeDeltaFunctionKernelList(kWidth, kHeight) kernel = afwMath.LinearCombinationKernel(basisKernelList, spFunc) numBasisKernels = kernel.getNKernelParameters() maxVal = 1.01 + ((numSpParams - 1) * 0.1) sParamList = [ numpy.arange(kInd + 1.0, kInd + maxVal, 0.1) for kInd in range(numBasisKernels) ] kernel.setSpatialParameters(sParamList) refKernel = kernel.refactor() self.assert_(refKernel) errStr = self.compareKernels(kernel, refKernel, compareParams=False) if errStr: self.fail("failed with %s for spOrder=%s (numSpCoeff=%s)" % (errStr, spOrder, numSpParams))
def testSpatiallyVaryingDeltaFunctionLinearCombination(self): """Test convolution with a spatially varying LinearCombinationKernel of delta function basis kernels. """ kWidth = 2 kHeight = 2 # create spatially model sFunc = 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, -0.5 / self.width, -0.5 / self.height), (0.0, 1.0 / self.width, 0.0 / self.height), (0.0, 0.0 / self.width, 1.0 / self.height), (0.5, 0.0, 0.0), ) basisKernelList = makeDeltaFunctionKernelList(kWidth, kHeight) kernel = afwMath.LinearCombinationKernel(basisKernelList, sFunc) kernel.setSpatialParameters(sParams) for maxInterpDist, rtol, methodStr in ( (0, 1.0e-5, "brute force"), (10, 1.0e-3, "interpolation over 10 x 10 pixels"), ): self.runStdTest( kernel, kernelDescr= "Spatially varying LinearCombinationKernel of delta function kernels using %s" % (methodStr, ), maxInterpDist=maxInterpDist, rtol=rtol)
def testSVLinearCombinationKernel(self): """Test a spatially varying LinearCombinationKernel """ kWidth = 3 kHeight = 2 # create image arrays for the basis kernels basisImArrList = [] imArr = np.zeros((kWidth, kHeight), dtype=float) imArr += 0.1 imArr[kWidth // 2, :] = 0.9 basisImArrList.append(imArr) imArr = np.zeros((kWidth, kHeight), dtype=float) imArr += 0.2 imArr[:, kHeight // 2] = 0.8 basisImArrList.append(imArr) # create a list of basis kernels from the images kVec = [] for basisImArr in basisImArrList: basisImage = afwImage.makeImageFromArray( basisImArr.transpose().copy()) kernel = afwMath.FixedKernel(basisImage) kVec.append(kernel) # create spatially varying linear combination kernel spFunc = afwMath.PolynomialFunction2D(1) # spatial parameters are a list of entries, one per kernel parameter; # each entry is a list of spatial parameters sParams = ( (0.0, 1.0, 0.0), (0.0, 0.0, 1.0), ) k = afwMath.LinearCombinationKernel(kVec, spFunc) k.setSpatialParameters(sParams) with lsst.utils.tests.getTempFilePath(".fits") as filename: k.writeFits(filename) k2 = afwMath.LinearCombinationKernel.readFits(filename) self.kernelCheck(k, k2) kImage = afwImage.ImageD(lsst.geom.Extent2I(kWidth, kHeight)) for colPos, rowPos, coeff0, coeff1 in [ (0.0, 0.0, 0.0, 0.0), (1.0, 0.0, 1.0, 0.0), (0.0, 1.0, 0.0, 1.0), (1.0, 1.0, 1.0, 1.0), (0.5, 0.5, 0.5, 0.5), ]: k2.computeImage(kImage, False, colPos, rowPos) kImArr = kImage.getArray().transpose() refKImArr = (basisImArrList[0] * coeff0) + \ (basisImArrList[1] * coeff1) if not np.allclose(kImArr, refKImArr): self.fail(f"{k2.__class__.__name__} = {kImArr} != {refKImArr} " f"at colPos={colPos}, rowPos={rowPos}")
def setUp(self): self.val1, self.val2 = 10, 100 self.image1 = afwImage.ImageF(afwGeom.ExtentI(100, 200)) self.image1.set(self.val1) self.image2 = afwImage.ImageF(self.image1.getDimensions()) self.image2.set(self.val2) self.function = afwMath.PolynomialFunction2D(2) self.function.setParameters(range(self.function.getNParameters()))
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 testBad(self): ti = afwImage.MaskedImageF(geom.Extent2I(100, 100)) ti.getVariance().set(0.1) ti[50, 50, afwImage.LOCAL] = (1., 0x0, 1.) sKernel = self.makeSpatialKernel(2) si = afwImage.MaskedImageF(ti.getDimensions()) convolutionControl = afwMath.ConvolutionControl() convolutionControl.setDoNormalize(True) afwMath.convolve(si, ti, sKernel, convolutionControl) bbox = geom.Box2I(geom.Point2I(25, 25), geom.Point2I(75, 75)) si = afwImage.MaskedImageF(si, bbox, origin=afwImage.LOCAL) ti = afwImage.MaskedImageF(ti, bbox, origin=afwImage.LOCAL) kc = ipDiffim.KernelCandidateF(50., 50., ti, si, self.ps) badGaussian = afwMath.GaussianFunction2D(1., 1., 0.) badKernel = afwMath.AnalyticKernel(self.ksize, self.ksize, badGaussian) basisList = [] basisList.append(badKernel) badSpatialKernelFunction = afwMath.PolynomialFunction2D(0) badSpatialKernel = afwMath.LinearCombinationKernel( basisList, badSpatialKernelFunction) badSpatialKernel.setSpatialParameters([[ 1, ]]) sBg = afwMath.PolynomialFunction2D(1) bgCoeffs = [10., 10., 10.] sBg.setParameters(bgCoeffs) # must be initialized bskv = ipDiffim.BuildSingleKernelVisitorF(self.kList, self.ps) bskv.processCandidate(kc) self.assertEqual(kc.isInitialized(), True) askv = ipDiffim.AssessSpatialKernelVisitorF(badSpatialKernel, sBg, self.ps) askv.processCandidate(kc) self.assertEqual(askv.getNProcessed(), 1) self.assertEqual(askv.getNRejected(), 1) self.assertEqual(kc.getStatus(), afwMath.SpatialCellCandidate.BAD)
def testTicket873(self): """Demonstrate ticket 873: convolution of a MaskedImage with a spatially varying LinearCombinationKernel of basis kernels with low covariance gives incorrect variance. """ # create spatial model sFunc = 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, -0.5/self.width, -0.5/self.height), (0.0, 1.0/self.width, 0.0/self.height), (0.0, 0.0/self.width, 1.0/self.height), ) # create three kernels with some non-overlapping pixels # (non-zero pixels in one kernel vs. zero pixels in other kernels); # note: the extreme example of this is delta function kernels, but this # is less extreme basisKernelList = [] kImArr = numpy.zeros([5, 5], dtype=float) kImArr[1:4, 1:4] = 0.5 kImArr[2, 2] = 1.0 kImage = afwImage.makeImageFromArray(kImArr) basisKernelList.append(afwMath.FixedKernel(kImage)) kImArr[:, :] = 0.0 kImArr[0:2, 0:2] = 0.125 kImArr[3:5, 3:5] = 0.125 kImage = afwImage.makeImageFromArray(kImArr) basisKernelList.append(afwMath.FixedKernel(kImage)) kImArr[:, :] = 0.0 kImArr[0:2, 3:5] = 0.125 kImArr[3:5, 0:2] = 0.125 kImage = afwImage.makeImageFromArray(kImArr) basisKernelList.append(afwMath.FixedKernel(kImage)) kernel = afwMath.LinearCombinationKernel(basisKernelList, sFunc) kernel.setSpatialParameters(sParams) for maxInterpDist, rtol, methodStr in ( (0, 1.0e-5, "brute force"), (10, 3.0e-3, "interpolation over 10 x 10 pixels"), ): self.runStdTest( kernel, kernelDescr="Spatially varying LinearCombinationKernel of basis " "kernels with low covariance, using %s" % ( methodStr,), maxInterpDist=maxInterpDist, rtol=rtol)
def testDFuncDParameters(self): """Test that we can differentiate the Function2 with respect to its parameters""" nOrder = 3 params = [] for i in range((nOrder + 1) * (nOrder + 2) // 2): # deterministic pretty-random numbers params.append(math.sin(1 + i)) f = afwMath.PolynomialFunction2D(params) for (x, y) in [(2, 1), (1, 2), (2, 2)]: dFdC = f.getDFuncDParameters(x, y) self.assertAlmostEqual( f(x, y), sum([params[i] * dFdC[i] for i in range(len(params))]))
def getDeltaLinearCombinationKernel(kSize, imSize, spOrder): """Return a LinearCombinationKernel of delta functions @param kSize: kernel size (scalar; height = width) @param x, y imSize: image size """ kernelList = afwMath.KernelList() for ctrX in range(kSize): for ctrY in range(kSize): kernelList.append(afwMath.DeltaFunctionKernel(kSize, kSize, afwGeom.Point2I(ctrX, ctrY))) polyFunc = afwMath.PolynomialFunction2D(spOrder) kernel = afwMath.LinearCombinationKernel(kernelList, polyFunc) spParams = getSpatialParameters(len(kernelList), polyFunc) kernel.setSpatialParameters(spParams); return kernel
def getSeparableKernel(kSize, imSize, spOrder): """Return spatially varying separable kernel: a pair of 1-d Gaussians @param kSize: kernel size (scalar; height = width) @param x, y imSize: image size """ gaussFunc = afwMath.GaussianFunction1D(1) polyFunc = afwMath.PolynomialFunction2D(spOrder) kernel = afwMath.SeparableKernel(kSize, kSize, gaussFunc, gaussFunc, polyFunc) minSigma = 0.1 maxSigma = 3.0 spParams = getSpatialParameters(2, polyFunc) spParams[0][0:3] = [minSigma, (maxSigma - minSigma) / float(imSize[0]), 0.0] spParams[1][0:3] = [minSigma, 0.0, (maxSigma - minSigma) / float(imSize[0])] kernel.setSpatialParameters(spParams); return kernel
def getAnalyticKernel(kSize, imSize, spOrder): """Return spatially varying analytic kernel: a Gaussian @param kSize: kernel size (scalar; height = width) @param x, y imSize: image size """ gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0) polyFunc = afwMath.PolynomialFunction2D(spOrder) kernel = afwMath.AnalyticKernel(kSize, kSize, gaussFunc, polyFunc) minSigma = 0.1 maxSigma = 3.0 spParams = getSpatialParameters(3, polyFunc) spParams[0][0:3] = [minSigma, (maxSigma - minSigma) / float(imSize[0]), 0.0] spParams[1][0:3] = [minSigma, 0.0, (maxSigma - minSigma) / float(imSize[1])] kernel.setSpatialParameters(spParams); return kernel
def testCast(self): for instance in (afwMath.Chebyshev1Function1F(2), afwMath.GaussianFunction1F(1.0), afwMath.LanczosFunction1F(3), afwMath.NullFunction1F(), afwMath.PolynomialFunction1F(2)): Class = type(instance) base = instance.clone() self.assertEqual(type(base), afwMath.Function1F) derived = Class.cast(base) self.assertEqual(type(derived), Class) for instance in (afwMath.Chebyshev1Function1D(2), afwMath.GaussianFunction1D(1.0), afwMath.LanczosFunction1D(3), afwMath.NullFunction1D(), afwMath.PolynomialFunction1D(2)): Class = type(instance) base = instance.clone() self.assertEqual(type(base), afwMath.Function1D) derived = Class.cast(base) self.assertEqual(type(derived), Class) for instance in (afwMath.Chebyshev1Function2F(2), afwMath.GaussianFunction2F(1.0, 1.0), afwMath.DoubleGaussianFunction2F(1.0), afwMath.LanczosFunction2F(3), afwMath.NullFunction2F(), afwMath.PolynomialFunction2F(2)): Class = type(instance) base = instance.clone() self.assertEqual(type(base), afwMath.Function2F) derived = Class.cast(base) self.assertEqual(type(derived), Class) for instance in (afwMath.Chebyshev1Function2D(2), afwMath.GaussianFunction2D(1.0, 1.0), afwMath.DoubleGaussianFunction2D(1.0), afwMath.LanczosFunction2D(3), afwMath.NullFunction2D(), afwMath.PolynomialFunction2D(2)): Class = type(instance) base = instance.clone() self.assertEqual(type(base), afwMath.Function2D) derived = Class.cast(base) self.assertEqual(type(derived), Class)
def testSpatiallyVaryingGaussianLinerCombination(self): """Test convolution with a spatially varying LinearCombinationKernel of two Gaussian basis kernels. """ kWidth = 5 kHeight = 5 # create spatial model for nBasisKernels in (3, 4): # at 3 the kernel will not be refactored, at 4 it will be sFunc = 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, -0.01 / self.width, -0.01 / self.height), (0.0, 0.01 / self.width, 0.0 / self.height), (0.0, 0.0 / self.width, 0.01 / self.height), (0.5, 0.005 / self.width, -0.005 / self.height), )[:nBasisKernels] gaussParamsList = ( (1.5, 1.5, 0.0), (2.5, 1.5, 0.0), (2.5, 1.5, math.pi / 2.0), (2.5, 2.5, 0.0), )[:nBasisKernels] basisKernelList = makeGaussianKernelList(kWidth, kHeight, gaussParamsList) kernel = afwMath.LinearCombinationKernel(basisKernelList, 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="%s with %d basis kernels convolved using %s" % ("Spatially Varying Gaussian Analytic Kernel", nBasisKernels, methodStr), maxInterpDist=maxInterpDist, rtol=rtol)
def testMinimize2(self): variances = numpy.array([0.01, 0.01, 0.01, 0.01]) xPositions = numpy.array([0.0, 1.0, 0.0, 1.0]) yPositions = numpy.array([0.0, 0.0, 1.0, 1.0]) polyOrder = 1 polyFunc = afwMath.PolynomialFunction2D(polyOrder) modelParams = [0.1, 0.2, 0.3] polyFunc.setParameters(modelParams) measurements = [] for x, y in zip(xPositions, yPositions): measurements.append(polyFunc(x, y)) print "measurements=", measurements # Set up initial guesses nParameters = polyFunc.getNParameters() initialParameters = numpy.zeros(nParameters, float) stepsize = numpy.ones(nParameters, float) stepsize *= 0.1 # Minimize! fitResults = afwMath.minimize( polyFunc, initialParameters, stepsize, measurements, variances, xPositions, yPositions, 0.1, ) print "modelParams=", modelParams print "fitParams =", fitResults.parameterList self.assert_(fitResults.isValid, "fit failed") if not numpy.allclose(modelParams, fitResults.parameterList): self.fail("fit not accurate")
def testMinimize2(self): variances = np.array([0.01, 0.01, 0.01, 0.01]) xPositions = np.array([0.0, 1.0, 0.0, 1.0]) yPositions = np.array([0.0, 0.0, 1.0, 1.0]) polyOrder = 1 polyFunc = afwMath.PolynomialFunction2D(polyOrder) modelParams = [0.1, 0.2, 0.3] polyFunc.setParameters(modelParams) measurements = [] for x, y in zip(xPositions, yPositions): measurements.append(polyFunc(x, y)) print("measurements=", measurements) # Set up initial guesses nParameters = polyFunc.getNParameters() initialParameters = np.zeros(nParameters, float) stepsize = np.ones(nParameters, float) stepsize *= 0.1 # Minimize! fitResults = afwMath.minimize( polyFunc, initialParameters, stepsize, measurements, variances, xPositions, yPositions, 0.1, ) print("modelParams=", modelParams) print("fitParams =", fitResults.parameterList) self.assertTrue(fitResults.isValid, "fit failed") self.assertFloatsAlmostEqual(np.array(modelParams), np.array(fitResults.parameterList), 1e-11)
def testComputeImageRaise(self): """Test Kernel.computeImage raises OverflowException iff doNormalize True and kernel sum exactly 0 """ kWidth = 4 kHeight = 3 polyFunc1 = afwMath.PolynomialFunction1D(0) polyFunc2 = afwMath.PolynomialFunction2D(0) analKernel = afwMath.AnalyticKernel(kWidth, kHeight, polyFunc2) kImage = afwImage.ImageD(analKernel.getDimensions()) for coeff in (-1, -1e-99, 0, 1e99, 1): analKernel.setKernelParameters([coeff]) analKernel.computeImage(kImage, False) fixedKernel = afwMath.FixedKernel(kImage) sepKernel = afwMath.SeparableKernel( kWidth, kHeight, polyFunc1, polyFunc1) sepKernel.setKernelParameters([coeff, coeff]) kernelList = [] kernelList.append(analKernel) lcKernel = afwMath.LinearCombinationKernel(kernelList, [1]) self.assertFalse(lcKernel.isDeltaFunctionBasis()) doRaise = (coeff == 0) self.basicTestComputeImageRaise( analKernel, doRaise, "AnalyticKernel") self.basicTestComputeImageRaise( fixedKernel, doRaise, "FixedKernel") self.basicTestComputeImageRaise( sepKernel, doRaise, "SeparableKernel") self.basicTestComputeImageRaise( lcKernel, doRaise, "LinearCombinationKernel") lcKernel.setKernelParameters([0]) self.basicTestComputeImageRaise( lcKernel, True, "LinearCombinationKernel")
def getGaussianLinearCombinationKernel(kSize, imSize, spOrder): """Return a LinearCombinationKernel with 5 bases, each a Gaussian @param kSize: kernel size (scalar; height = width) @param x, y imSize: image size """ kernelList = afwMath.KernelList() for fwhmX, fwhmY, angle in ( (2.0, 2.0, 0.0), (0.5, 4.0, 0.0), (0.5, 4.0, math.pi / 4.0), (0.5, 4.0, math.pi / 2.0), (4.0, 4.0, 0.0), ): gaussFunc = afwMath.GaussianFunction2D(fwhmX, fwhmY, angle) kernelList.append(afwMath.AnalyticKernel(kSize, kSize, gaussFunc)) polyFunc = afwMath.PolynomialFunction2D(spOrder) kernel = afwMath.LinearCombinationKernel(kernelList, polyFunc) spParams = getSpatialParameters(len(kernelList), polyFunc) kernel.setSpatialParameters(spParams); return kernel
def testSVSeparableKernel(self): """Test spatially varying SeparableKernel 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), ) gaussFunc = afwMath.GaussianFunction1D(1.0) kernel = afwMath.SeparableKernel( kWidth, kHeight, gaussFunc, 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), ) kernel.setSpatialParameters(newSParams) errStr = self.compareKernels(kernel, kernelClone) if not errStr: self.fail( "Clone was modified by changing original's spatial parameters")
def testSVLinearCombinationKernel(self): """Test a spatially varying LinearCombinationKernel """ kWidth = 3 kHeight = 2 pol = pexPolicy.Policy() additionalData = dafBase.PropertySet() loc = dafPersist.LogicalLocation( os.path.join(testPath, "data", "kernel6.boost")) persistence = dafPersist.Persistence.getPersistence(pol) # create image arrays for the basis kernels basisImArrList = [] imArr = np.zeros((kWidth, kHeight), dtype=float) imArr += 0.1 imArr[kWidth // 2, :] = 0.9 basisImArrList.append(imArr) imArr = np.zeros((kWidth, kHeight), dtype=float) imArr += 0.2 imArr[:, kHeight // 2] = 0.8 basisImArrList.append(imArr) # create a list of basis kernels from the images kVec = [] for basisImArr in basisImArrList: basisImage = afwImage.makeImageFromArray( basisImArr.transpose().copy()) kernel = afwMath.FixedKernel(basisImage) kVec.append(kernel) # create spatially varying linear combination kernel spFunc = afwMath.PolynomialFunction2D(1) # spatial parameters are a list of entries, one per kernel parameter; # each entry is a list of spatial parameters sParams = ( (0.0, 1.0, 0.0), (0.0, 0.0, 1.0), ) k = afwMath.LinearCombinationKernel(kVec, spFunc) k.setSpatialParameters(sParams) 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("LinearCombinationKernel", storageList2, additionalData) self.kernelCheck(k, k2) kImage = afwImage.ImageD(afwGeom.Extent2I(kWidth, kHeight)) for colPos, rowPos, coeff0, coeff1 in [ (0.0, 0.0, 0.0, 0.0), (1.0, 0.0, 1.0, 0.0), (0.0, 1.0, 0.0, 1.0), (1.0, 1.0, 1.0, 1.0), (0.5, 0.5, 0.5, 0.5), ]: k2.computeImage(kImage, False, colPos, rowPos) kImArr = kImage.getArray().transpose() refKImArr = (basisImArrList[0] * coeff0) + \ (basisImArrList[1] * coeff1) if not np.allclose(kImArr, refKImArr): self.fail( "%s = %s != %s at colPos=%s, rowPos=%s" % (k2.__class__.__name__, kImArr, refKImArr, colPos, rowPos))