Coverage for tests/test_matrixBuilder.py: 7%
262 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-05-01 03:42 -0700
« prev ^ index » next coverage.py v7.5.0, created at 2024-05-01 03:42 -0700
1#
2# LSST Data Management System
3# Copyright 2008-2017 LSST Corporation.
4#
5# This product includes software developed by the
6# LSST Project (http://www.lsst.org/).
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the LSST License Statement and
19# the GNU General Public License along with this program. If not,
20# see <http://www.lsstcorp.org/LegalNotices/>.
21#
23import unittest
25import numpy as np
27import lsst.geom
28import lsst.utils.tests
29import lsst.afw.geom.ellipses
30import lsst.shapelet.tests
31import lsst.afw.image
34class MatrixBuilderTestCase(lsst.shapelet.tests.ShapeletTestCase):
36 def setUp(self):
37 np.random.seed(500)
38 self.xD = np.random.randn(50)
39 self.yD = np.random.randn(50)
40 self.xF = self.xD.astype(np.float32)
41 self.yF = self.yD.astype(np.float32)
43 def checkAccessors(self, obj, basisSize):
44 self.assertEqual(obj.getDataSize(), self.xD.size)
45 self.assertEqual(obj.getBasisSize(), basisSize)
47 def testShapeletMatrixBuilder(self):
48 function = self.makeRandomShapeletFunction(order=4)
49 size = function.getCoefficients().size
50 function.getCoefficients()[:] = np.random.randn(size)
51 basis = lsst.shapelet.MultiShapeletBasis(size)
52 basis.addComponent(1.0, function.getOrder(), np.identity(size))
53 factoryF = lsst.shapelet.MatrixBuilderF.Factory(self.xF, self.yF, function.getOrder())
54 factoryD = lsst.shapelet.MatrixBuilderD.Factory(self.xD, self.yD, function.getOrder())
55 # we should get the same results with an appropriately simple MultiShapeletBasis
56 compoundFactoryF = lsst.shapelet.MatrixBuilderF.Factory(self.xF, self.yF, basis)
57 compoundFactoryD = lsst.shapelet.MatrixBuilderD.Factory(self.xD, self.yD, basis)
58 self.checkAccessors(factoryF, size)
59 self.checkAccessors(factoryD, size)
60 self.checkAccessors(compoundFactoryF, size)
61 self.checkAccessors(compoundFactoryD, size)
62 builder1F = factoryF()
63 builder1D = factoryD()
64 self.checkAccessors(builder1F, size)
65 self.checkAccessors(builder1D, size)
66 workspaceF = lsst.shapelet.MatrixBuilderF.Workspace(factoryF.computeWorkspace())
67 workspaceD = lsst.shapelet.MatrixBuilderD.Workspace(factoryD.computeWorkspace())
68 builder2F = factoryF(workspaceF)
69 builder2D = factoryD(workspaceD)
70 self.assertEqual(workspaceF.getRemaining(), 0)
71 self.assertEqual(workspaceD.getRemaining(), 0)
72 self.checkAccessors(builder2F, size)
73 self.checkAccessors(builder2D, size)
74 builder3F = compoundFactoryF()
75 builder3D = compoundFactoryD()
76 self.checkAccessors(builder3F, size)
77 self.checkAccessors(builder3D, size)
78 matrix1F = builder1F(function.getEllipse())
79 matrix1D = builder1D(function.getEllipse())
80 matrix2F = builder2F(function.getEllipse())
81 matrix2D = builder2D(function.getEllipse())
82 matrix3F = builder3F(function.getEllipse())
83 matrix3D = builder3D(function.getEllipse())
84 # same code, different workspace
85 self.assertFloatsAlmostEqual(matrix1D, matrix2D, rtol=0.0, atol=0.0)
86 # same code, different workspace
87 self.assertFloatsAlmostEqual(matrix1F, matrix2F, rtol=0.0, atol=0.0)
88 # same code, different construction pattern
89 self.assertFloatsAlmostEqual(matrix1F, matrix3F, rtol=0.0, atol=0.0)
90 # same code, different construction pattern
91 self.assertFloatsAlmostEqual(matrix1D, matrix3D, rtol=0.0, atol=0.0)
92 # same code, different construction pattern
93 self.assertFloatsAlmostEqual(matrix1F, matrix2F, rtol=1E-7, atol=0.0)
94 # Finally, check against a completely different implementation (which is tested elsewhere)
95 checkEvaluator = function.evaluate()
96 checkVector = checkEvaluator(self.xD, self.yD)
97 self.assertFloatsAlmostEqual(np.dot(matrix1D, function.getCoefficients()),
98 checkVector, rtol=1E-13, atol=1E-14)
100 def testRemappedShapeletMatrixBuilder(self):
101 function = self.makeRandomShapeletFunction(order=4)
102 size = 6
103 radius = 3.2
104 remapMatrix = np.random.randn(function.getCoefficients().size, size)
105 coefficients = np.random.randn(size)
106 function.getCoefficients()[:] = np.dot(remapMatrix, coefficients)
107 basis = lsst.shapelet.MultiShapeletBasis(size)
108 basis.addComponent(radius, function.getOrder(), remapMatrix)
109 factoryF = lsst.shapelet.MatrixBuilderF.Factory(self.xF, self.yF, basis)
110 factoryD = lsst.shapelet.MatrixBuilderD.Factory(self.xD, self.yD, basis)
111 self.checkAccessors(factoryF, size)
112 self.checkAccessors(factoryD, size)
113 builder1F = factoryF()
114 builder1D = factoryD()
115 self.checkAccessors(builder1F, size)
116 self.checkAccessors(builder1D, size)
117 workspaceF = lsst.shapelet.MatrixBuilderF.Workspace(factoryF.computeWorkspace())
118 workspaceD = lsst.shapelet.MatrixBuilderD.Workspace(factoryD.computeWorkspace())
119 builder2F = factoryF(workspaceF)
120 builder2D = factoryD(workspaceD)
121 self.assertEqual(workspaceF.getRemaining(), 0)
122 self.assertEqual(workspaceD.getRemaining(), 0)
123 self.checkAccessors(builder2F, size)
124 self.checkAccessors(builder2D, size)
125 matrix1F = builder1F(function.getEllipse())
126 matrix1D = builder1D(function.getEllipse())
127 matrix2F = builder2F(function.getEllipse())
128 matrix2D = builder2D(function.getEllipse())
129 # same code, different workspace
130 self.assertFloatsAlmostEqual(matrix1D, matrix2D, rtol=0.0, atol=0.0)
131 # same code, different workspace
132 self.assertFloatsAlmostEqual(matrix1F, matrix2F, rtol=0.0, atol=0.0)
133 # same code, different precision
134 self.assertFloatsAlmostEqual(matrix1F, matrix2F, rtol=1E-7, atol=0.0)
135 # Finally, check against a completely different implementation (which is tested elsewhere)
136 function.getEllipse().scale(radius)
137 checkEvaluator = function.evaluate()
138 checkVector = checkEvaluator(self.xD, self.yD)
139 self.assertFloatsAlmostEqual(np.dot(matrix1D, coefficients), checkVector, rtol=1E-13, atol=1E-14)
141 def testConvolvedShapeletMatrixBuilder(self):
142 function = self.makeRandomShapeletFunction(order=4)
143 psf = self.makeRandomMultiShapeletFunction(nComponents=1)
144 size = function.getCoefficients().size
145 function.getCoefficients()[:] = np.random.randn(size)
146 basis = lsst.shapelet.MultiShapeletBasis(size)
147 basis.addComponent(1.0, function.getOrder(), np.identity(size))
148 factoriesF = [lsst.shapelet.MatrixBuilderF.Factory(self.xF, self.yF, function.getOrder(),
149 psf.getComponents()[0]),
150 lsst.shapelet.MatrixBuilderF.Factory(self.xF, self.yF, basis, psf),
151 ]
152 factoriesD = [lsst.shapelet.MatrixBuilderD.Factory(self.xD, self.yD, function.getOrder(),
153 psf.getComponents()[0]),
154 lsst.shapelet.MatrixBuilderD.Factory(self.xD, self.yD, basis, psf),
155 ]
156 lastF = None
157 for factory in factoriesF:
158 self.checkAccessors(factory, size)
159 workspace = lsst.shapelet.MatrixBuilderF.Workspace(factory.computeWorkspace())
160 builder1 = factory()
161 builder2 = factory(workspace)
162 self.checkAccessors(builder1, size)
163 self.checkAccessors(builder2, size)
164 self.assertEqual(workspace.getRemaining(), 0)
165 matrix1 = builder1(function.getEllipse())
166 matrix2 = builder2(function.getEllipse())
167 # same code, different workspace
168 self.assertFloatsAlmostEqual(matrix1, matrix2, rtol=0.0, atol=0.0)
169 if lastF is not None:
170 # same code, different construction
171 self.assertFloatsAlmostEqual(matrix1, lastF, rtol=0.0, atol=0.0)
172 lastF = matrix1
173 lastD = None
174 for factory in factoriesD:
175 self.checkAccessors(factory, size)
176 workspace = lsst.shapelet.MatrixBuilderD.Workspace(factory.computeWorkspace())
177 builder1 = factory()
178 builder2 = factory(workspace)
179 self.checkAccessors(builder1, size)
180 self.checkAccessors(builder2, size)
181 self.assertEqual(workspace.getRemaining(), 0)
182 matrix1 = builder1(function.getEllipse())
183 matrix2 = builder2(function.getEllipse())
184 # same code, different workspace
185 self.assertFloatsAlmostEqual(matrix1, matrix2, rtol=0.0, atol=0.0)
186 if lastD is not None:
187 # same code, different construction
188 self.assertFloatsAlmostEqual(matrix1, lastD, rtol=0.0, atol=0.0)
189 lastD = matrix1
190 # same code, different precision
191 self.assertFloatsAlmostEqual(lastF, lastD, rtol=1E-6, atol=1E-5)
193 # Finally, check against a completely different implementation (which is tested elsewhere)
194 convolved = function.convolve(psf.getComponents()[0])
195 checkEvaluator = convolved.evaluate()
196 checkVector = checkEvaluator(self.xD, self.yD)
197 self.assertFloatsAlmostEqual(np.dot(lastD, function.getCoefficients()), checkVector, rtol=1E-13)
199 def testRemappedConvolvedShapeletMatrixBuilder(self):
200 function = self.makeRandomShapeletFunction(order=4)
201 psf = self.makeRandomMultiShapeletFunction(nComponents=1)
202 size = 6
203 radius = 3.2
204 remapMatrix = np.random.randn(function.getCoefficients().size, size)
205 coefficients = np.random.randn(size)
206 function.getCoefficients()[:] = np.dot(remapMatrix, coefficients)
207 basis = lsst.shapelet.MultiShapeletBasis(size)
208 basis.addComponent(radius, function.getOrder(), remapMatrix)
209 factoryF = lsst.shapelet.MatrixBuilderF.Factory(self.xF, self.yF, basis, psf)
210 factoryD = lsst.shapelet.MatrixBuilderD.Factory(self.xD, self.yD, basis, psf)
211 matrixF = None
212 for factory in (factoryF, factoryD):
213 self.checkAccessors(factory, size)
214 workspace = factory.Workspace(factory.computeWorkspace())
215 builder1 = factory()
216 builder2 = factory(workspace)
217 self.checkAccessors(builder1, size)
218 self.checkAccessors(builder2, size)
219 self.assertEqual(workspace.getRemaining(), 0)
220 matrix1 = builder1(function.getEllipse())
221 matrix2 = builder2(function.getEllipse())
222 # same code, different workspace
223 self.assertFloatsAlmostEqual(matrix1, matrix2, rtol=0.0, atol=0.0)
224 if matrixF is None:
225 matrixF = matrix1
226 matrixD = matrix1
227 # same code, different precision
228 self.assertFloatsAlmostEqual(matrixF, matrixD, rtol=1E-4, atol=0.0)
230 # Finally, check against a completely different implementation (which is tested elsewhere)
231 function.getEllipse().scale(radius)
232 convolved = function.convolve(psf.getComponents()[0])
233 checkEvaluator = convolved.evaluate()
234 checkVector = checkEvaluator(self.xD, self.yD)
235 self.assertFloatsAlmostEqual(np.dot(matrixD, coefficients), checkVector, rtol=1E-12, atol=1E-12)
237 def testCompoundMatrixBuilder(self):
238 ellipse = lsst.afw.geom.ellipses.Ellipse(lsst.afw.geom.ellipses.Axes(4.0, 3.0, 1.0),
239 lsst.geom.Point2D(3.2, 1.0))
240 radii = [0.7, 1.2]
241 orders = [4, 3]
242 size = 8
243 functions = [self.makeRandomShapeletFunction(order=order, ellipse=ellipse, scale=radius)
244 for radius, order in zip(radii, orders)]
245 remapMatrices = [np.random.randn(f.getCoefficients().size, size) for f in functions]
246 coefficients = np.random.randn(size)
247 basis = lsst.shapelet.MultiShapeletBasis(size)
248 for radius, function, matrix in zip(radii, functions, remapMatrices):
249 function.getCoefficients()[:] = np.dot(matrix, coefficients)
250 basis.addComponent(radius, function.getOrder(), matrix)
251 factoryF = lsst.shapelet.MatrixBuilderF.Factory(self.xF, self.yF, basis)
252 factoryD = lsst.shapelet.MatrixBuilderD.Factory(self.xD, self.yD, basis)
253 self.checkAccessors(factoryF, size)
254 self.checkAccessors(factoryD, size)
255 builder1F = factoryF()
256 builder1D = factoryD()
257 self.checkAccessors(builder1F, size)
258 self.checkAccessors(builder1D, size)
259 workspaceF = lsst.shapelet.MatrixBuilderF.Workspace(factoryF.computeWorkspace())
260 workspaceD = lsst.shapelet.MatrixBuilderD.Workspace(factoryD.computeWorkspace())
261 builder2F = factoryF(workspaceF)
262 builder2D = factoryD(workspaceD)
263 self.assertEqual(workspaceF.getRemaining(), 0)
264 self.assertEqual(workspaceD.getRemaining(), 0)
265 self.checkAccessors(builder2F, size)
266 self.checkAccessors(builder2D, size)
267 matrix1F = builder1F(ellipse)
268 matrix1D = builder1D(ellipse)
269 matrix2F = builder2F(ellipse)
270 matrix2D = builder2D(ellipse)
271 # same code, different workspace
272 self.assertFloatsAlmostEqual(matrix1D, matrix2D, rtol=0.0, atol=0.0)
273 # same code, different workspace
274 self.assertFloatsAlmostEqual(matrix1F, matrix2F, rtol=0.0, atol=0.0)
275 # same code, different precision
276 self.assertFloatsAlmostEqual(matrix1F, matrix2F, rtol=1E-7, atol=0.0)
277 # Finally, check against a completely different implementation (which is tested elsewhere)
278 checkVector = np.zeros(self.xD.shape, dtype=float)
279 for function in functions:
280 checkEvaluator = function.evaluate()
281 checkVector += checkEvaluator(self.xD, self.yD)
282 self.assertFloatsAlmostEqual(np.dot(matrix1D, coefficients), checkVector, rtol=1E-13, atol=1E-14)
284 def testConvolvedCompoundMatrixBuilder(self):
285 ellipse = lsst.afw.geom.ellipses.Ellipse(lsst.afw.geom.ellipses.Axes(4.0, 3.0, 1.0),
286 lsst.geom.Point2D(3.2, 1.0))
287 radii = [0.7, 1.2]
288 orders = [4, 3]
289 size = 8
290 functions = [self.makeRandomShapeletFunction(order=order, ellipse=ellipse, scale=radius)
291 for radius, order in zip(radii, orders)]
292 psf = self.makeRandomMultiShapeletFunction()
293 remapMatrices = [np.random.randn(f.getCoefficients().size, size) for f in functions]
294 coefficients = np.random.randn(size)
295 basis = lsst.shapelet.MultiShapeletBasis(size)
296 for radius, function, matrix in zip(radii, functions, remapMatrices):
297 function.getCoefficients()[:] = np.dot(matrix, coefficients)
298 basis.addComponent(radius, function.getOrder(), matrix)
299 msf = lsst.shapelet.MultiShapeletFunction(functions)
300 factoryF = lsst.shapelet.MatrixBuilderF.Factory(self.xF, self.yF, basis, psf)
301 factoryD = lsst.shapelet.MatrixBuilderD.Factory(self.xD, self.yD, basis, psf)
302 self.checkAccessors(factoryF, size)
303 self.checkAccessors(factoryD, size)
304 builder1F = factoryF()
305 builder1D = factoryD()
306 self.checkAccessors(builder1F, size)
307 self.checkAccessors(builder1D, size)
308 workspaceF = lsst.shapelet.MatrixBuilderF.Workspace(factoryF.computeWorkspace())
309 workspaceD = lsst.shapelet.MatrixBuilderD.Workspace(factoryD.computeWorkspace())
310 builder2F = factoryF(workspaceF)
311 builder2D = factoryD(workspaceD)
312 self.assertEqual(workspaceF.getRemaining(), 0)
313 self.assertEqual(workspaceD.getRemaining(), 0)
314 self.checkAccessors(builder2F, size)
315 self.checkAccessors(builder2D, size)
316 matrix1F = builder1F(ellipse)
317 matrix1D = builder1D(ellipse)
318 matrix2F = builder2F(ellipse)
319 matrix2D = builder2D(ellipse)
320 # same code, different workspace
321 self.assertFloatsAlmostEqual(matrix1D, matrix2D, rtol=0.0, atol=0.0)
322 # same code, different workspace
323 self.assertFloatsAlmostEqual(matrix1F, matrix2F, rtol=0.0, atol=0.0)
324 # same code, different precision
325 self.assertFloatsAlmostEqual(matrix1F, matrix2F, rtol=1E-7, atol=0.0)
327 # Finally, check against a completely different implementation (which is tested elsewhere)
328 convolved = msf.convolve(psf)
329 checkEvaluator = convolved.evaluate()
330 checkVector = checkEvaluator(self.xD, self.yD)
331 self.assertFloatsAlmostEqual(np.dot(matrix1D, coefficients), checkVector, rtol=1E-13, atol=1E-14)
334class MemoryTester(lsst.utils.tests.MemoryTestCase):
335 pass
338def setup_module(module):
339 lsst.utils.tests.init()
342if __name__ == "__main__": 342 ↛ 343line 342 didn't jump to line 343, because the condition on line 342 was never true
343 lsst.utils.tests.init()
344 unittest.main()