Coverage for tests/test_kernelIo1.py : 9%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
2#
3# LSST Data Management System
4# Copyright 2008, 2009, 2010 LSST Corporation.
5#
6# This product includes software developed by the
7# LSST Project (http://www.lsst.org/).
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the LSST License Statement and
20# the GNU General Public License along with this program. If not,
21# see <http://www.lsstcorp.org/LegalNotices/>.
22#
24import unittest
25import os
27import numpy as np
29import lsst.utils.tests
30import lsst.geom
31import lsst.afw.image as afwImage
32import lsst.afw.math as afwMath
33from lsst.log import Log
35# Change the level to Log.DEBUG to see debug messages
36Log.getLogger("afw.math.KernelFormatter").setLevel(Log.INFO)
39testPath = os.path.abspath(os.path.dirname(__file__))
42class KernelIOTestCase(unittest.TestCase):
43 """A test case for Kernel I/O"""
45 def kernelCheck(self, k1, k2):
46 self.assertEqual(k1.getWidth(), k2.getWidth())
47 self.assertEqual(k1.getHeight(), k2.getHeight())
48 self.assertEqual(k1.getCtr(), k2.getCtr())
49 with self.assertWarns(FutureWarning):
50 self.assertEqual(k1.getCtrX(), k2.getCtrX())
51 self.assertEqual(k1.getCtrY(), k2.getCtrY())
52 self.assertEqual(k1.getNKernelParameters(), k2.getNKernelParameters())
53 self.assertEqual(k1.getNSpatialParameters(),
54 k2.getNSpatialParameters())
55 self.assertEqual(k1.getKernelParameters(), k2.getKernelParameters())
56 self.assertEqual(k1.getSpatialParameters(), k2.getSpatialParameters())
57 self.assertEqual(k1.isSpatiallyVarying(), k2.isSpatiallyVarying())
58 self.assertEqual(k1.toString(), k2.toString())
60 def testFixedKernel(self):
61 """Test FixedKernel using a ramp function
62 """
63 kWidth = 5
64 kHeight = 6
66 inArr = np.arange(kWidth * kHeight, dtype=float)
67 inArr.shape = [kWidth, kHeight]
69 inImage = afwImage.ImageD(lsst.geom.Extent2I(kWidth, kHeight))
70 for row in range(inImage.getHeight()):
71 for col in range(inImage.getWidth()):
72 inImage[col, row, afwImage.LOCAL] = inArr[col, row]
74 k = afwMath.FixedKernel(inImage)
76 with lsst.utils.tests.getTempFilePath(".fits") as filename:
77 k.writeFits(filename)
78 k2 = afwMath.FixedKernel.readFits(filename)
80 self.kernelCheck(k, k2)
82 outImage = afwImage.ImageD(k2.getDimensions())
83 k2.computeImage(outImage, False)
85 outArr = outImage.getArray().transpose()
86 if not np.allclose(inArr, outArr):
87 self.fail(f"{k2.__class__.__name__} = {inArr} != {outArr} (not normalized)")
88 normInArr = inArr / inArr.sum()
89 normOutImage = afwImage.ImageD(k2.getDimensions())
90 k2.computeImage(normOutImage, True)
91 normOutArr = normOutImage.getArray().transpose()
92 if not np.allclose(normOutArr, normInArr):
93 self.fail(f"{k2.__class__.__name__} = {normInArr} != {normOutArr} (normalized)")
95 def testAnalyticKernel(self):
96 """Test AnalyticKernel using a Gaussian function
97 """
98 kWidth = 5
99 kHeight = 8
101 gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0)
102 k = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc)
103 center = k.getCtr()
104 fArr = np.zeros(shape=[k.getWidth(), k.getHeight()], dtype=float)
105 for xsigma in (0.1, 1.0, 3.0):
106 for ysigma in (0.1, 1.0, 3.0):
107 for angle in (0.0, 0.4, 1.1):
108 gaussFunc.setParameters((xsigma, ysigma, angle))
109 # compute array of function values and normalize
110 for row in range(k.getHeight()):
111 y = row - center.getY()
112 for col in range(k.getWidth()):
113 x = col - center.getX()
114 fArr[col, row] = gaussFunc(x, y)
115 fArr /= fArr.sum()
117 k.setKernelParameters((xsigma, ysigma, angle))
119 with lsst.utils.tests.getTempFilePath(".fits") as filename:
120 k.writeFits(filename)
121 k2 = afwMath.AnalyticKernel.readFits(filename)
123 self.kernelCheck(k, k2)
125 kImage = afwImage.ImageD(k2.getDimensions())
126 k2.computeImage(kImage, True)
127 kArr = kImage.getArray().transpose()
128 if not np.allclose(fArr, kArr):
129 self.fail(f"{k2.__class__.__name__} = {kArr} != {fArr} "
130 f"for xsigma={xsigma}, ysigma={ysigma}")
132 def testDeltaFunctionKernel(self):
133 """Test DeltaFunctionKernel
134 """
135 for kWidth in range(1, 4):
136 for kHeight in range(1, 4):
137 for activeCol in range(kWidth):
138 for activeRow in range(kHeight):
139 kernel = afwMath.DeltaFunctionKernel(kWidth, kHeight,
140 lsst.geom.Point2I(activeCol, activeRow))
142 with lsst.utils.tests.getTempFilePath(".fits") as filename:
143 kernel.writeFits(filename)
144 k2 = afwMath.DeltaFunctionKernel.readFits(filename)
146 self.kernelCheck(kernel, k2)
147 self.assertEqual(kernel.getPixel(), k2.getPixel())
149 kImage = afwImage.ImageD(k2.getDimensions())
150 kSum = k2.computeImage(kImage, False)
151 self.assertEqual(kSum, 1.0)
152 kArr = kImage.getArray().transpose()
153 self.assertEqual(kArr[activeCol, activeRow], 1.0)
154 kArr[activeCol, activeRow] = 0.0
155 self.assertEqual(kArr.sum(), 0.0)
157 @unittest.skip("SeparableKernel does not yet support table persistence")
158 def testSeparableKernel(self):
159 """Test SeparableKernel using a Gaussian function
160 """
161 kWidth = 5
162 kHeight = 8
164 gaussFunc1 = afwMath.GaussianFunction1D(1.0)
165 k = afwMath.SeparableKernel(kWidth, kHeight, gaussFunc1, gaussFunc1)
166 center = k.getCtr()
167 fArr = np.zeros(shape=[k.getWidth(), k.getHeight()], dtype=float)
168 np.zeros(shape=[k.getWidth(), k.getHeight()], dtype=float)
169 gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0)
170 for xsigma in (0.1, 1.0, 3.0):
171 gaussFunc1.setParameters((xsigma,))
172 for ysigma in (0.1, 1.0, 3.0):
173 gaussFunc.setParameters((xsigma, ysigma, 0.0))
174 # compute array of function values and normalize
175 for row in range(k.getHeight()):
176 y = row - center.getY()
177 for col in range(k.getWidth()):
178 x = col - center.getX()
179 fArr[col, row] = gaussFunc(x, y)
180 fArr /= fArr.sum()
182 k.setKernelParameters((xsigma, ysigma))
184 with lsst.utils.tests.getTempFilePath(".fits") as filename:
185 k.writeFits(filename)
186 k2 = afwMath.SeparableKernel.readFits(filename)
188 self.kernelCheck(k, k2)
190 kImage = afwImage.ImageD(k2.getDimensions())
191 k2.computeImage(kImage, True)
192 kArr = kImage.getArray().transpose()
193 if not np.allclose(fArr, kArr):
194 self.fail(f"{k2.__class__.__name__} = {kArr} != {fArr} "
195 f"for xsigma={xsigma}, ysigma={ysigma}")
197 def testLinearCombinationKernel(self):
198 """Test LinearCombinationKernel using a set of delta basis functions
199 """
200 kWidth = 3
201 kHeight = 2
203 # create list of kernels
204 basisImArrList = []
205 kVec = []
206 for row in range(kHeight):
207 for col in range(kWidth):
208 kernel = afwMath.DeltaFunctionKernel(
209 kWidth, kHeight, lsst.geom.Point2I(col, row))
210 basisImage = afwImage.ImageD(kernel.getDimensions())
211 kernel.computeImage(basisImage, True)
212 basisImArrList.append(basisImage.getArray().transpose().copy())
213 kVec.append(kernel)
215 kParams = [0.0]*len(kVec)
216 k = afwMath.LinearCombinationKernel(kVec, kParams)
217 for ii in range(len(kVec)):
218 kParams = [0.0]*len(kVec)
219 kParams[ii] = 1.0
220 k.setKernelParameters(kParams)
222 with lsst.utils.tests.getTempFilePath(".fits") as filename:
223 k.writeFits(filename)
224 k2 = afwMath.LinearCombinationKernel.readFits(filename)
226 self.kernelCheck(k, k2)
228 kIm = afwImage.ImageD(k2.getDimensions())
229 k2.computeImage(kIm, True)
230 kImArr = kIm.getArray().transpose()
231 if not np.allclose(kImArr, basisImArrList[ii]):
232 self.fail(f"{k2.__class__.__name__} = {kImArr} != {basisImArrList[ii]} "
233 f"for the {ii}'th basis kernel")
235 def testSVLinearCombinationKernel(self):
236 """Test a spatially varying LinearCombinationKernel
237 """
238 kWidth = 3
239 kHeight = 2
241 # create image arrays for the basis kernels
242 basisImArrList = []
243 imArr = np.zeros((kWidth, kHeight), dtype=float)
244 imArr += 0.1
245 imArr[kWidth//2, :] = 0.9
246 basisImArrList.append(imArr)
247 imArr = np.zeros((kWidth, kHeight), dtype=float)
248 imArr += 0.2
249 imArr[:, kHeight//2] = 0.8
250 basisImArrList.append(imArr)
252 # create a list of basis kernels from the images
253 kVec = []
254 for basisImArr in basisImArrList:
255 basisImage = afwImage.makeImageFromArray(
256 basisImArr.transpose().copy())
257 kernel = afwMath.FixedKernel(basisImage)
258 kVec.append(kernel)
260 # create spatially varying linear combination kernel
261 spFunc = afwMath.PolynomialFunction2D(1)
263 # spatial parameters are a list of entries, one per kernel parameter;
264 # each entry is a list of spatial parameters
265 sParams = (
266 (0.0, 1.0, 0.0),
267 (0.0, 0.0, 1.0),
268 )
270 k = afwMath.LinearCombinationKernel(kVec, spFunc)
271 k.setSpatialParameters(sParams)
273 with lsst.utils.tests.getTempFilePath(".fits") as filename:
274 k.writeFits(filename)
275 k2 = afwMath.LinearCombinationKernel.readFits(filename)
277 self.kernelCheck(k, k2)
279 kImage = afwImage.ImageD(lsst.geom.Extent2I(kWidth, kHeight))
280 for colPos, rowPos, coeff0, coeff1 in [
281 (0.0, 0.0, 0.0, 0.0),
282 (1.0, 0.0, 1.0, 0.0),
283 (0.0, 1.0, 0.0, 1.0),
284 (1.0, 1.0, 1.0, 1.0),
285 (0.5, 0.5, 0.5, 0.5),
286 ]:
287 k2.computeImage(kImage, False, colPos, rowPos)
288 kImArr = kImage.getArray().transpose()
289 refKImArr = (basisImArrList[0] * coeff0) + \
290 (basisImArrList[1] * coeff1)
291 if not np.allclose(kImArr, refKImArr):
292 self.fail(f"{k2.__class__.__name__} = {kImArr} != {refKImArr} "
293 f"at colPos={colPos}, rowPos={rowPos}")
295 def testSetCtr(self):
296 """Test setCtrCol/Row"""
297 kWidth = 3
298 kHeight = 4
300 gaussFunc = afwMath.GaussianFunction2D(1.0, 1.0, 0.0)
301 k = afwMath.AnalyticKernel(kWidth, kHeight, gaussFunc)
302 for xCtr in range(kWidth):
303 for yCtr in range(kHeight):
304 ctr = lsst.geom.Point2I(xCtr, yCtr)
305 k.setCtr(ctr)
307 with lsst.utils.tests.getTempFilePath(".fits") as filename:
308 k.writeFits(filename)
309 k2 = afwMath.AnalyticKernel.readFits(filename)
311 self.kernelCheck(k, k2)
313 self.assertEqual(k2.getCtr(), ctr)
316class TestMemory(lsst.utils.tests.MemoryTestCase):
317 pass
320def setup_module(module):
321 lsst.utils.tests.init()
324if __name__ == "__main__": 324 ↛ 325line 324 didn't jump to line 325, because the condition on line 324 was never true
325 lsst.utils.tests.init()
326 unittest.main()