Coverage for tests/test_matrixBuilder.py: 7%

262 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-11-25 02:37 -0800

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# 

22 

23import unittest 

24 

25import numpy as np 

26 

27import lsst.geom 

28import lsst.utils.tests 

29import lsst.afw.geom.ellipses 

30import lsst.shapelet.tests 

31import lsst.afw.image 

32 

33 

34class MatrixBuilderTestCase(lsst.shapelet.tests.ShapeletTestCase): 

35 

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) 

42 

43 def checkAccessors(self, obj, basisSize): 

44 self.assertEqual(obj.getDataSize(), self.xD.size) 

45 self.assertEqual(obj.getBasisSize(), basisSize) 

46 

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) 

99 

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) 

140 

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) 

192 

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) 

198 

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) 

229 

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) 

236 

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) 

283 

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) 

326 

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) 

332 

333 

334class MemoryTester(lsst.utils.tests.MemoryTestCase): 

335 pass 

336 

337 

338def setup_module(module): 

339 lsst.utils.tests.init() 

340 

341 

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()